MySQLインデックスのメンテナンス


12

MySQLでインデックスを維持して断片化を防ぎ、いくつかのクエリの実行を何らかの方法で最適化する方法について、多くの調査を行いました。

テーブルで使用可能な最大スペースとデータとインデックスで使用されるスペースの比率を計算する式に精通しています。

しかし、私の主な質問はまだ答えられていません。おそらく、これはSQL Serverでのインデックスのメンテナンスに精通しているためであり、MySQLでもそれはある程度似ているはずだと思う傾向があります。

SQLサーバーでは、いくつかのインデックスを設定でき、それぞれに異なるレベルの断片化を設定できます。次に、1つをピックアップして、残りに影響を与えることなく、その特定のインデックスで「REORGANIZE」または「REBUILD」操作を実行できます。

私の知る限りでは、このような「テーブルの断片化」はなく、SQL Serverは「テーブルの断片化」を修正するためのツールを提供していません。それが提供するのは、内部および外部の断片化だけでなく、インデックスの断片化(インデックスによって使用されるページ数とそのページの完全性と連続性の間の比率のように理解される)をチェックするツールです。

少なくとも私にとっては、そのすべてを理解するのは非常に簡単です。

MySQLでインデックスを維持する番になると、前述のように「テーブルの断片化」の概念しか存在しません。

MySQLのテーブルには複数のインデックスを含めることができますが、その有名な式で「断片化率」を確認すると、各インデックスの断片化が表示されず、テーブル全体が表示されます。

MySQLでインデックスを最適化したい場合、(SQL Serverのように)操作する特定のインデックスを選択しません。代わりに、テーブル全体で「OPTIMIZE」操作を実行します。これは、おそらくすべてのインデックスに影響します。

MySQLでテーブルが最適化されると、データ+インデックスVS全体のスペースによって使用されるスペースの比率が減少します。これは、ハードドライブでのある種の物理的な再編成を示唆し、物理スペースの減少につながります。ただし、インデックスの断片化は、物理的なスペースだけでなく、挿入と更新によって時間の経過とともに変更されたツリーの構造に関するものです。

最後に、InnoDB / MySQLにテーブルを取得しました。このテーブルには、300万レコード、105列、55インデックスがあります。2.1GBのインデックスを除いて1.5GBです。

このテーブルは、更新、挿入のために毎日何千回もヒットしています(実際にはレコードを削除しません)。

そのテーブルは何年も前に作成されており、誰もインデックスを維持している人はいません。

そこに巨大な断片化を見つけることを期待していましたが、規定どおりに断片化計算を実行すると

free_space / (data_length + index_length)

断片化が0.2%しかないことがわかります。私見はかなり非現実的です。

したがって、大きな質問は次のとおりです。

  1. テーブル全体ではなく、MySQLの特定のインデックスの断片化をチェックするにはどうすればよいですか
  2. SQL Serverのように、OPTIMIZE TABLEは実際にインデックスの内部/外部断片化を修正しますか?
  3. MySQLでテーブルを最適化すると、実際にテーブルのすべてのインデックスが再構築されますか?
  4. (ツリー自体を再構築せずに)インデックスの物理スペースを減らすと、実際にパフォーマンスが向上すると考えるのは現実的ですか?

最適化テーブルは確かにinnodbのクラスター化インデックスをクリーンアップします

1
それは素晴らしい質問であり、プログラミングの問題ではありません。それが属する場所に移動されます:>

回答:


6

インデックスの断片化は過大評価されています。それについて心配しないでください。

2つの隣接する、やや空のブロックが、自然な処理としてInnoDBによってマージされます。

BTreeでのランダムなアクションにより、BTreeは平均69%のフルに自然に引き寄せられます。もちろん、これは100%ではありませんが、「修正」のオーバーヘッドは価値がありません。

SHOW TABLE STATUS いくつかのメトリックを提供しますが、欠陥があります-「Data_free」には特定の「空き」スペースが含まれますが、その他の「空き」スペースは含まれません。

各ブロックには未使用のスペースがあります。空き16KBブロック。無料の「エクステント」(nMBチャンク)。刈り取りを待っているMVCC行。非リーフノードには独自のフラグメンテーションがあります。等

PerconaとOracleでは、インデックスの大きさ(ブロック数)の見方が異なります。「無料」の定義が限られているため、どちらも役に立ちません。ブロック(各16KB)はチャンク(数MB)に割り当てられているようで、あらゆる種類の断片化があると思われます。実際には、通常、これらのマルチMBチャンクのほとんどの1つです。そしてOPTIMIZE TABLE、必ずしもスペースを取り戻すわけではありません。

SQL ServerがBTreesを使用している場合、「断片化がない」と言うのは嘘です。「ブロック分割」で何が起こるか考えてください。または、継続的なデフラグのオーバーヘッドについて考えてください。どちらにしても失う。

さらに、テーブルとインデックスは基本的に同じ構造であることに注意してください。

  • B +ツリー、いくつかのインデックスに基づく
  • 「データ」は主キーに基づいています。各セカンダリインデックスは、そのインデックスに基づくBツリーです。
  • 「データ」のリーフノードには、テーブルのすべての列が含まれます。
  • セカンダリインデックスのリーフノードには、そのセカンダリインデックスの列と、PRIMARY KEYの列が含まれています。

がある場合innodb_file_per_table = ONは、.ibdファイルのサイズを確認することで、OPTIMIZE TABLEの後の収縮(ある場合)を明確に確認できます。の場合OFF、情報はに埋め込まれてibdata1いますが、SHOW TABLE STATUSが、すべての「空き」スペースがすべてのテーブルに属しているため、かなり正確な場合あります。まあ、事前に割り当てられたチャンクを除いて。

新しく最適化されたfile-per-tableテーブルには、4M、5M、6M、または7MのData_freeがあることに気付くでしょう。繰り返しになりますが、これは事前割り当てであり、詳細を提供することができません。

私は10年以上にわたってInnoDBを使用してきました。私は、大小を問わず、何千もの異なるテーブルで作業してきました。本当に必要なのは、1,000のテーブルのうち1つだけだと私は言いますOPTIMIZE TABLE。他のテーブルで使用するのはもったいないです。

105列はたくさんありますが、多すぎないでしょう。

1つのテーブルに55のインデックスがありますか?それは悪いです。つまり、1回あたり55回の更新INSERTです。それについてさらに議論しましょう。INDEX(a)あなたも持っているならそれは役に立たないことに注意してくださいINDEX(a,b)。そして、INDEX(flag)低いため、カーディナリティの無駄です。(だがINDEX(flag, foo)、役に立つかもしれません。)

Q1:データまたはセカンダリインデックスのいずれかですべての形式の断片化をチェックする良い方法はありません。

Q2、Q3:新しいテーブルとすべての行でテーブルをOPTIMIZE TABLE再構築し、次にと。PK順にデータを再挿入すると、データが適切にデフラグされます。インデックスは別の問題です。CREATEingINSERTingRENAMEingDROPping

Q4:できること DROPreCREATE、各インデックスはそれをクリーンアップします。しかし、これは非常に遅いプロセスです。5.6にはいくつかの高速化がありますが、最適化に役立つかどうかはわかりません。

ことも可能でありALTER TABLE ... DISABLE KEYS、その後、ENABLEそれら。これにより、すべてのセカンダリインデックスを一度に効率的に再構築できます。


リック、私はファイルではなく「105」フィールドを意味しました
ニコラス

1

テーブル全体ではなく、MySQLの特定のインデックスの断片化をチェックするにはどうすればよいですか

パス。

SQL Serverのように、OPTIMIZE TABLEは実際にインデックスの内部/外部断片化を修正しますか?

テーブルとそのインデックスを完全に再構築します。

MySQLでテーブルを最適化すると、実際にテーブルのすべてのインデックスが再構築されますか?

それは同じ質問と同じ答えです。

(ツリー自体を再構築せずに)インデックスの物理スペースを減らすと、実際にパフォーマンスが向上すると考えるのは現実的ですか?

ツリー再構築せずにスペース削減できると考えるのは現実的ではありません。彼らは一緒に行きます。


#1に答えるにはあまり正確ではありませんがSHOW TABLE STATUS LIKE 'mytable'data freeコラムでヒントを与えます。dev.mysql.com/doc/refman/5.6/en/show-table-status.html
Jehad Keriaki

わかっていますが、それでも特定のインデックスのスペースが不足しています
ニコラス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.