MyISAMとInnoDBのベスト


17

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

回答:


14

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オプションと組み合わせて、同じ結果を得ることができます。

確かに、これはMyISAMで機能し、効果的に機能します。InnoDBに対してALTER TABLE ... ORDER BY col1、col2、...、colnを実行できます。ここで、列はPRIMARY KEYの列である場合とそうでない場合があります。これはInnoDBの結果を高速化するものではありません。そのとおりです...毎回gen_clust_indexを参照する必要があります。

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

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に行IDの順序でテーブルが配置されます。これは、InnoDBでわずかな結果しか生成しない可能性があります。そのとおりです...毎回gen_clust_indexを参照する必要があります。

さて、少しばかげたことをしましょう。クエリするNoSQLインターフェイスがあります(SELECTのみ)MyISAMとInnoDBは、HandlerSocket(以前のHANLDER)インターフェイスと呼ばれていました。これにより、すべてのSQL、ACID、およびMVCCプロトコルをバイパスできるデータにアクセスできます。可能ですが、私的な方法はコーディングと保守が複雑すぎます。私の知る限り、HandlerSocketインターフェイスがgen_clust_indexと対話するかどうかを示す印刷物はありません。

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


3

クラスタ化インデックスは、おそらくあり、従来のスピン・ドライブ上のInnoDBの同時実行性能の理由。

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

ディスクI / Oは高価です。したがって、それを減らすことは、並行性を改善するための大きな利点です。

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


3

短い答え:いいえ。

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

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


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

これは事実ですが、一つの慰めは、商用データベースが深くよりもできるだけ太くしようとすることです。確認するには、データに対して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リーフページ(〜8GB)がありましたが、上記のページは416ページ(6.5MB)のみでした。実稼働データでこのコマンドを数回実行しましたが、数百億から数十億のレコードがあり、レベル1〜3ページ+リーフページしかないときはいつも驚きます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.