web-dev-qa-db-ja.com

MyISAMとInnoDBのベスト

RAM)の制限により、同時実行パフォーマンスの利点を得ながら、InnoDBでクラスター化インデックスの代わりにMyISAMと同じインデックスを使用することは可能ですか?

17
Rick James

InnoDBの内部にある gen_clust_index (クラスタ化インデックス)には、ROWIDとともに主キーのエントリが格納されています。 gen_clust_indexの使用に関して興味深いのは、作成する一意でないインデックスには常に、テーブルのgen_clust_indexに対応するROWIDがあるということです。したがって、セカンダリインデックス用とgen_clust_index用の二重のインデックスルックアップが常に存在します。

テーブルまたは主キーのレイアウトを改善しようとすると、gen_clust_indexが原因で無効になるか、せいぜい限界的な結果になります。

MyISAMを主キーの順序で並べ替えようとする人もいます。 MySQLデータベースの設計とチューニング、ページ236パラグラフ7、「インデックス順でのテーブルの保存」の副題: によると==

テーブルから広範囲のインデックス付きデータを頻繁に取得する場合、または同じインデックスキーで結果を一貫してソートする場合は、-sort-recordsオプションを指定してmyisamchkを実行することを検討してください。そうすることで、MySQLにテーブルのデータをインデックスと同じ物理的な順序でソートするように指示し、これらの種類の操作を高速化することができます。または、ALTER TABLEステートメントを特定の列オプションのORDER BYと組み合わせて、同じ結果を得ることができます。

確かに、これは機能し、効果的に機能しますFOR MyISAM。列がプライマリキーの列である場合とそうでない場合があるInnoDBに対して、ALTER TABLE ... ORDER BY col1、col2、...、colnを実行できます。 ...その通りです...毎回gen_clust_indexを参照する必要があるため、これはInnoDBの結果を高速化しません。

一部の人々は、ALTER TABLE mydb.mytb ROW_FORMAT=Fixed;を使用してテーブルの行フォーマットをFIXEDにすることができ、他の変更なしで読み取りパフォーマンスを20%向上させることができます。これは機能し、効果的に機能しますFOR MyISAM。 ...その通りです...毎回gen_clust_indexを参照する必要があるため、これはInnoDBの結果を高速化しません。

Mydb.mytbという名前のInnoDBテーブルで次を実行できます。

CREATE TABLE mydb.mytc LIKE mydb.mytb;
INSERT INTO mydb.mytc SELECT * FROM mydb.mytb ORDER BY col1,col2,...coln;
ALTER TABLE mydb.mytb RENAME mydb.mytd;
ALTER TABLE mydb.mytc RENAME mydb.mytb;
DROP TABLE mydb.mytd;

これにより、gen_clust_indexにテーブルがROWID順に配置されます。 ...その通りです...毎回gen_clust_indexを参照する必要があるため、これはInnoDBに最低限の結果をもたらす可能性があります。

さて、ちょっとばかげてみましょう。 MyISAMとInnoDBをクエリするNoSQLインターフェースがあります HandlerSocket(以前の名前はHANLDER)インターフェース と呼ばれます。これにより、すべてのSQLをバイパスできるデータにアクセスできます [〜#〜] acid [〜#〜] 、および [〜#〜] mvcc [〜#〜] =プロトコル。可能ではありますが、私見ではコードの作成と保守が複雑すぎます。申し訳ありませんが、HandlerSocketインターフェースがgen_clust_indexと対話するかどうかを示すものは何もありません。

要約すると、猫の皮をむく方法はたくさんあります。この場合、猫(gen_clust_index)を手に入れることはできません。 MyISAMがその読み取りパフォーマンス、テーブルの順序付け、テーブルの行形式の柔軟性、およびそれをサポートするツールのために存在し続けるのは、これが理由だと思います。 InnoDBは、ACID準拠の性質を中心に設計されたままであり、勇気ある人がInnoDBソースコードを取得して、MyISAMとInnoDBの両方の中で最高のものに変換します。

14
RolandoMySQLDBA

短い答え:いいえ。

InnoDBは主キーを介してクラスター化し、主キーがない場合、最初の一意のインデックスを選択します。一意のインデックスがない場合、クラスタリング用の非表示の6バイトのキーが作成されます。

非表示の6バイトのキーがある場合、セカンダリインデックスは(MyISAMのように)行の場所への正確なポインターではなく、このキーを参照するため、最終的にセカンダリキートラバーサル、次にプライマリキートラバーサルでレコードを検索します。 。


あなたのリーフページを見つけるために常にこのパスを歩く必要があるので、効率的に検索するにはすべてのルートノードがメモリ内にあるはずなので、あなたはあなたの質問から少し外挿するために、ツリーとのメモリフィットについて心配していると思いますか?

これは本当ですが、1つの慰めは商業データベースがそれらの木を深くではなく、可能な限り太くしようとすることです。確認するには、データに対して xtrabackup --stats を実行してみてください。例えば:

<INDEX STATISTICS>
  table: test/table1, index: PRIMARY, space id: 12, root page 3
  estimated statistics in dictionary:
    key vals: 25265338, leaf pages 497839, size pages 498304
  real statistics:
     level 2 pages: pages=1, data=5395 bytes, data/pages=32%
     level 1 pages: pages=415, data=6471907 bytes, data/pages=95%
        leaf pages: recs=25958413, pages=497839, data=7492026403 bytes, data/pages=91%

497839枚のリーフページ(約8 GB)がありましたが、上に416ページ(6.5 MB)しかありませんでした。このコマンドを本番データで数回実行しましたが、数百億から数十億のレコードがあり、レベル1〜3ページ+リーフページしかない場合は、常に驚きます。

3
Morgan Tocker

クラスター化インデックス は、おそらく従来のスピンドライブでのInnoDBの同時実行パフォーマンスの理由です。

クラスター化されたインデックスを介した行へのアクセスは、行データがインデックス検索と同じページにあるため、高速です。テーブルが大きい場合、クラスター化インデックスアーキテクチャは、インデックスレコードとは異なるページを使用して行データを格納するストレージ組織と比較して、ディスクI/O操作を節約することがよくあります。 (たとえば、MyISAMはデータ行に1つのファイルを使用し、インデックスレコードに別のファイルを使用します。)

ディスクI/Oは高価です。したがって、これを減らすことは、同時実行性を向上させるための大きなメリットです。

ディスクI/Oが安くなり、ボトルネックが少なくなった場合(SSDテクノロジーがより安定するなど)、OracleはInnoDBインデックスの動作を変更する場合があります。同じテクノロジーで「RAMの制限」の問題が少なくなるため、同じままになる可能性が高くなります。

3
Derek Downey