web-dev-qa-db-ja.com

多くのインデックスを持つInnoDBとMyISAM

この質問は状況に大きく左右されると思いますので、正解か不正解かはわかりませんが、精神的な練習のため、とにかく質問してみます。

私のデータベースには、サイトの中心となるMyISAMテーブルがあります。その周りに作成された多くの参照テーブルと、このテーブルの行IDに直接リンクする他の多くのテーブルがあります。テーブルのサイズは約26万行で、28のフィールドがあり、そのほとんどがvarcharsとintです。私はそれに約15のインデックスを持っています(データは約70 MiB、インデックスは約80 MiBです)。おそらく、1日に数百回の書き込みがあるのに対し、数万回の読み取りがあります。私のデータベースはSSDドライブにあります。

今私の質問です。このテーブルをInnoDBテーブルに変更すると有益でしょうか?私はシステムを拡張してAPIトラフィックも含めるように取り組んでいます。つまり、テーブルはさらにクエリされ、すべてが可能な限りスムーズに実行されるようにしたいと考えています。このため、私はそれをInnoDBに変換することに少し傾いています。ただし、テーブルには多くのインデックスが必要なため、MyISAMがより効果的に機能する可能性があると考えています。誰かが私の決心を手伝ってくれる?よろしくお願いします1

編集:(コメントからjcolebrandによって追加)

私はずっと前にインデックスを追加し、いくつかをPHPコードベースに変更したので、いくつかのインデックスは古くなっているかもしれませんが、全体的には、そうです、それらはすべて使用されています。実行します。テーブルに対する多くの異なるタイプのクエリ。異なるクエリ、異なるインデックス。ただし、ここでの主な質問は、テーブルの読み取りパフォーマンスではなく、多くのインデックスでどのように実行されるかということです。InnoDBインデックスは、データと共にではなく「データのまま」/格納されますMyISAMのキーファイルの原則これは、テーブルロックの問題を上回らないほどのパフォーマンス低下を引き起こす可能性があることを心配しています。

6
Battle_707

おそらく、1日に数百回の書き込みがあるのに対し、数万回の読み取りがあります。私のデータベースはSSDドライブにあります。

このステートメントに基づいて、いくつかの数字を試してみましょう。たとえば、1日あたり500回の書き込みと1日あたり20,000回の読み取りがあるとします。次のように計算されます

  • 1日あたり97.56%の読み取り
  • 1日あたり2.44%の書き込み
  • 読み取り/書き込み40回

私がInnoDBを愛しているのと同じくらい、この場合MyISAMを選択する必要があります

理由#1

MyISAMテーブルは150MiBしかありません(70MiBデータ、80 MiBインデックス)

理由#2

セカンダリインデックスにはクラスター化インデックスへのキーがあるため、InnoDBインデックスは非常に肥大化する傾向があります。これにより、常に二重のインデックス検索が行われます。これは、書き込みが多い大規模なデータセットでは見落とされる可能性があります。

理由#3

InnoDBテーブルスペースは、ディスクスペースの自動再利用なしでMVCCが作成および破棄されるため、非常に肥大化する傾向があります。

  • innodb_file_per_table を無効にすると、システムテーブルスペースファイルibdata1は、ディスクスペースを再利用する可能性が0%と着実に増加します。 innodb_file_per_table を使用するには、InnoDBストレージエンジンを変換する必要があります。
  • innodb_file_per_table を有効にすると、個々のInnoDBに移動して次のコマンドを実行し、InnoDBテーブルを物理的に縮小できますmydb.mytable
    • OPTIMIZE TABLE mydb.mytable;
    • ALTER TABLE mydb.mytable ENGINE=InnoDB;

これはすべてMyISAMで回避できます

理由#4

InnoDBは、トランザクション制御のためにMVCCを実行することにより、個々の行を保護します。 1日の読み取りで発生するオーバーヘッドは、おそらく150 MiBを超えるでしょう。

もう2つまたは3つの理由を挙げることができますが、追いかけましょう:あなたのケースでMyISAMのパフォーマンスを改善できるものはありますか?なぜ、そうです。

あなたは次のように言いました

テーブルのサイズは約26万行で、28のフィールドがあり、そのほとんどがvarcharsとintです

多くのvarcharがある場合、読み取り/書き込みパフォーマンスを向上させるためにできることがいくつかあります。 MyISAMテーブルの場合mydb.mytable:次のコマンドを実行します:

ALTER TABLE mydb.mytable ROW_FORMAT=Fixed;

これにより、すべてのVARCHARがCHARとして扱われます。すべての行は正確に同じ長さになります。これにより、ディスク容量が80%〜100%増加します。あなたの場合、150 MiB MyISAMテーブルを2倍にして300 MiBにするとします。メリットはどこですか? MyISAMテーブルは、何も変更せずに20%から30%高速で読み書きできるようになりました。他に何も変更せずに、72、73ページから MySQLデータベースの設計とチューニング

私は過去にこれについて書きました:

6
RolandoMySQLDBA

テーブルから使用する種類(書き込みについて)については、2つの理由でinnoDBに切り替えることをお勧めします。

  • テーブルロックの代わりに行ロック:デッドロックまたは待機のリスクを軽減
  • データベースの整合性のネイティブチェック

読み取り時のパフォーマンスについて:ボリュームでinnodbに切り替えることを心配する必要はないと思います。あちこちで、何百万もの行データベースをinnodbの下で問題なく読み取ることができます。

ヒント:インデックスはすべて使用されていますか?現時点ではmysqlを忘れないでください(クエリ、テーブル参照)ごとに1つだけを使用します

1
Sebas

いいえ、まったく役に立たないと思います。私のメインテーブルが800k行に近いことと、RAIDはあるがSSDは似ていないことを除いて、私はあなたが説明している状況と非常に似ています。読み取りは、あなたと同じように、私のdb相互作用のほとんどであり、私はデータと同じくらい多くのインデックスデータを持っています。私の研究によりMyISAMを使用するようになり、その結果は見事なものでした。

0
colonelclick