ホームページ データベース mysql チュートリアル InnoDB 隔离模式对 MySQL 性能的影响_MySQL

InnoDB 隔离模式对 MySQL 性能的影响_MySQL

May 30, 2016 pm 05:09 PM
innodb mysql

过去的几个月我写了两篇文章,一篇是InnoDB 事务历史相关的危险债务,另一篇是关于MVCC 可能导致MySQL严重的性能问题的真相。在这篇文章里我将讨论一个相关的主题 – InnoDB 事务隔离模式,还有它们与MVCC(多版本并发控制)的关系,以及它们是如何影响MySQL性能的。

MySQL手册提供了一个关于MySQL支持的事务隔离模式的恰当描述 – 在这里我并不会再重复,而是聚焦到对性能的影响上。

SERIALIZABLE – 这是最强的隔离模式,本质上打败了在锁管理(设置锁是很昂贵的)的条件下,多版本控制对所有选择进行锁定造成大量的开销,还有你得到的并发。这个模式仅在MySQL应用中非常特殊的情况下使用。

REPEATABLE READ – 这是默认的隔离级别,通常它是相当不错的,对应用程序的便捷性来说也不错。它在第一次的时候读入所有数据 (假设使用标准的非锁读)。但是这有很高的代价 – InnoDB需要去维护事务记录,从一开始就要记录,它的代价是非常昂贵的。更为严重的情况是,程序频繁地更新和hot rows – 你真的就不想InnoDB去处理rows了,它有成百上千个版本。

在性能上的影响, 读和写都能够被影响。用select查询遍历多个行是代价高昂的,对于更新(update)也是,在MySQL 5.6中,尤其是版本控制看起来导致了严重的争用问题。

下面是例子:完全在内存中的数据集中运行 sysbench,并启动 transaction 、运行全表、扫描、查询几次,同时保持 transaction 是开着的:

sysbench  --num-threads=64 --report-interval=10 --max-time=0 --max-requests=0 --rand-type=pareto --oltp-table-size=80000000 --mysql-user=root --mysql-password= --mysql-db=sbinnodb  --test=/usr/share/doc/sysbench/tests/db/update_index.lua run

正如你可以看到的,写(write )操作的吞吐量大幅下降,并且持续走低,这时transaction 是开着的不仅是查询(query)操作运行的时候。在可复读的隔离模式下,当你已经选择了之外的transaction ,紧接着就是一个long transaction ,这也许是我能找到的最糟糕情况了。当然了在其他情况下看到回归算法(regression )

如果有人想测试,可以重复下面我用的查询集合:

READ UNCOMMITTED – 我觉得这是最难理解的隔离模式(悲催的只有2条文档),只描述了它的逻辑观点。如果你使用了这种隔离模式,你会看到数据控中所有发生的变化,即使是那些还没被提交的transactions 。这种隔离模式一种好的用例是:你能“watch”到大规模的有脏读(dirty reads)的UPDATE 语句,显示了哪行被改变了,哪些没有改变。

如果transaction 事务在运行的时候出错了,那么这个声明会显示还没被提交的和可能没被提交的变化,所以使用这个模式要小心为妙。有一些用例虽然不需要我们100%准确的数据,在这种情况下,这种模式就变得非常方便。

<ol class="dp-sql">
<li class="alt"><span><span class="keyword">select</span><span> </span><span class="func">avg</span><span>(length(c)) </span><span class="keyword">from</span><span> sbtest1;  </span></span></li>
<li>
<span class="keyword">begin</span><span>;  </span>
</li>
<li class="alt">
<span class="keyword">select</span><span> </span><span class="func">avg</span><span>(length(c)) </span><span class="keyword">from</span><span> sbtest1;  </span>
</li>
<li>
<span class="keyword">select</span><span> sleep(300);  </span>
</li>
<li class="alt">
<span class="keyword">commit</span><span>; </span>
</li>
</ol>
ログイン後にコピー

不只是可复读(Repeatable Read)的默认隔离级别,同样也可以用于InnoDB 逻辑备份 –  mydumper 或者 mysqldump –single-transaction

这些结果显示这个备份的方法恢复的时间太长而不能用于大型数据集合,同样这个方法受到性能影响,也不能用于频繁写入(write )的环境中。

READ COMMITTED 模式和REPEATABLE READ模式很相似,本质区别在于哪个版本都不在transaction中从头开始读取,取而代之的从当前语句开始读取。因此使用这种模式允许InnoDB少维护很多版本,特别是你没有很长的statements要允运行。如果你有很长的select要运行,如报表查询对性能的影响仍然很严重。

通常我认为好的做法是把READ COMITTED隔离模式做为默认,对于应用程序或者transactions 有必要就改成REPEATABLE READ。

那么,从性能角度来看,如何体现READ UNCOMMITTED?理论上,InnoDB 可以清除行版本,在READ UNCOMMITTED模式下即便是该语句已经开始执行之后,也可以创建。在实践中,由于一个bug或者一些复杂实现的细节做不到,语句开始仍然是行版本。所以,如果你在READ UNCOMMITTED声明中运行很长的SELECT,你会得到大量的行版本创建信息,就像你用了READ COMMITTED。No win here。

从SELECT方面还有一个重要的win - READ UNCOMMITTED隔离模式意味着InnoDB 不需要去检查旧的行版本 - 最后一行总是对的,这会使得性能有明显的改善,尤其是当undo空间已经在磁盘上溢出,查找旧的行版本会造成大量的IO读写。

也许上面这个select avg(k) from sbtest1;是我能找到的最好的查询例子了,能与之类似的更新工作量。假使READ UNCOMMITTED隔离模式在一分钟左右完成,我认为在READ COMMITTED隔离模式下没有完成过,因为新索引条目插入的速度要比扫描速度快。

最后思考:正确的使用InnoDB 隔离模式,能够让您的应用程序得到最佳性能。你得到的好处可能不同,在某些情况下,也可能没什么区别。关系到InnoDB 的历史版本,似乎好有好多工作要做,我希望在未来的MySQL中能解决。

英文原文:MySQL performance implications of InnoDB isolation modes

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPのビッグデータ構造処理スキル PHPのビッグデータ構造処理スキル May 08, 2024 am 10:24 AM

ビッグ データ構造の処理スキル: チャンキング: データ セットを分割してチャンクに処理し、メモリ消費を削減します。ジェネレーター: データ セット全体をロードせずにデータ項目を 1 つずつ生成します。無制限のデータ セットに適しています。ストリーミング: ファイルやクエリ結果を 1 行ずつ読み取ります。大きなファイルやリモート データに適しています。外部ストレージ: 非常に大規模なデータ セットの場合は、データをデータベースまたは NoSQL に保存します。

PHP で MySQL クエリのパフォーマンスを最適化するにはどうすればよいですか? PHP で MySQL クエリのパフォーマンスを最適化するにはどうすればよいですか? Jun 03, 2024 pm 08:11 PM

MySQL クエリのパフォーマンスは、検索時間を線形の複雑さから対数の複雑さまで短縮するインデックスを構築することで最適化できます。 PreparedStatement を使用して SQL インジェクションを防止し、クエリのパフォーマンスを向上させます。クエリ結果を制限し、サーバーによって処理されるデータ量を削減します。適切な結合タイプの使用、インデックスの作成、サブクエリの使用の検討など、結合クエリを最適化します。クエリを分析してボトルネックを特定し、キャッシュを使用してデータベースの負荷を軽減し、オーバーヘッドを最小限に抑えます。

PHP で MySQL のバックアップと復元を使用するにはどうすればよいですか? PHP で MySQL のバックアップと復元を使用するにはどうすればよいですか? Jun 03, 2024 pm 12:19 PM

PHP で MySQL データベースをバックアップおよび復元するには、次の手順を実行します。 データベースをバックアップします。 mysqldump コマンドを使用して、データベースを SQL ファイルにダンプします。データベースの復元: mysql コマンドを使用して、SQL ファイルからデータベースを復元します。

PHP を使用して MySQL テーブルにデータを挿入するにはどうすればよいですか? PHP を使用して MySQL テーブルにデータを挿入するにはどうすればよいですか? Jun 02, 2024 pm 02:26 PM

MySQLテーブルにデータを挿入するにはどうすればよいですか?データベースに接続する: mysqli を使用してデータベースへの接続を確立します。 SQL クエリを準備します。挿入する列と値を指定する INSERT ステートメントを作成します。クエリの実行: query() メソッドを使用して挿入クエリを実行します。成功すると、確認メッセージが出力されます。

MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法 MySQL 8.4 で mysql_native_password がロードされていないエラーを修正する方法 Dec 09, 2024 am 11:42 AM

MySQL 8.4 (2024 年時点の最新の LTS リリース) で導入された主な変更の 1 つは、「MySQL Native Password」プラグインがデフォルトで有効ではなくなったことです。さらに、MySQL 9.0 ではこのプラグインが完全に削除されています。 この変更は PHP および他のアプリに影響します

PHP で MySQL ストアド プロシージャを使用するにはどうすればよいですか? PHP で MySQL ストアド プロシージャを使用するにはどうすればよいですか? Jun 02, 2024 pm 02:13 PM

PHP で MySQL ストアド プロシージャを使用するには: PDO または MySQLi 拡張機能を使用して、MySQL データベースに接続します。ストアド プロシージャを呼び出すステートメントを準備します。ストアド プロシージャを実行します。結果セットを処理します (ストアド プロシージャが結果を返す場合)。データベース接続を閉じます。

PHP を使用して MySQL テーブルを作成するにはどうすればよいですか? PHP を使用して MySQL テーブルを作成するにはどうすればよいですか? Jun 04, 2024 pm 01:57 PM

PHP を使用して MySQL テーブルを作成するには、次の手順が必要です。 データベースに接続します。データベースが存在しない場合は作成します。データベースを選択します。テーブルを作成します。クエリを実行します。接続を閉じます。

Oracleデータベースとmysqlの違い Oracleデータベースとmysqlの違い May 10, 2024 am 01:54 AM

Oracle データベースと MySQL はどちらもリレーショナル モデルに基づいたデータベースですが、Oracle は互換性、スケーラビリティ、データ型、セキュリティの点で優れており、MySQL は速度と柔軟性に重点を置いており、小規模から中規模のデータ セットに適しています。 ① Oracle は幅広いデータ型を提供し、② 高度なセキュリティ機能を提供し、③ エンタープライズレベルのアプリケーションに適しています。① MySQL は NoSQL データ型をサポートし、② セキュリティ対策が少なく、③ 小規模から中規模のアプリケーションに適しています。

See all articles