web-dev-qa-db-ja.com

MySQLパーティショニング:パーティションの数と各パーティションのサイズの間にパフォーマンスのトレードオフはありますか?

効率的に分割したい大きなテーブル(数億行)があります。私の質問は、パーティションサイズとパーティション数の間にトレードオフがあるかどうかです。私が理解している限り、クエリは(ほとんどのクエリに対して)クエリに適用可能なパーティション内のみを検索する必要があるため、パーティションで使用される列に対するほとんどのクエリはより高速になります。したがって、効率を最大化するには、大きなテーブルを最大数のパーティションに分割する必要があるので、各パーティションをできるだけ小さくする必要があります。 MySQLの場合、これは1024パーティションを意味します。しかし、多数のパーティションを持つことにはパフォーマンス上の欠点がありますか?そうであれば、どのようにして最適なパーティション数を見つけるのでしょうか?

注: stackoverflowですでに似ている質問 がありますが、(私の観点から)マークを逃す回答は1つだけです。だから私は私自身の方法で質問を述べます...うまくいけばそれはより明確です

10
robguinness

それらを比較してみましょう

パーティションサイズ

次のものがある場合:

  • テーブル内の1億行
  • BTREEインデックス
  • BTREEの各ページは1024のキーを保持します

メトリックはどのように見えますか?

LOG(100000000)/ LOG(2)= 26.575424759099なので、ページツリーノードごとに1024キーを持つBTREEインデックスは、ツリーの高さが3(CEILING(LOG(100000000)/ LOG(1024)))しかありません。 3つのページノードのみの場合、アクセスされた各ツリーノードで必要なキーをバイナリ検索すると、約30個のキーが剪定および分離されます。

パーティション数

次のものがある場合:

  • テーブル内の1億行
  • BTREEインデックス
  • BTREEの各ページは1024のキーを保持します
  • 1024のパーティションを作成します

数値は少し異なります。

各パーティションには約97656行が必要です。メトリックは今どのようになりますか?

LOG(97656)/ LOG(2)= 16.575421065795なので、ページツリーノードあたり1024のキーを持つBTREEインデックスのツリーの高さは2(CEILING(LOG(97656)/ LOG(1024)))になります。 2ページのみのノードの場合、アクセスされた各ツリーノードで必要なキーをバイナリ検索すると、約20個のキーが剪定および分離されます。

結論

キーを分散すると、1つのツリーレベルが削除されるだけですが、基本的には1024のインデックスが作成されます。クエリは違いを知りません。検索時間は、パーティションを優先して、せいぜいわずかなものになるでしょう。ただし、すべてのデータがアクティブであることを確認してください。その他、 数個のパーティションしかヒットしない可能性がありますが、アクセス頻度の低いデータを含む他のパーティションは領域を占有するだけで、パーティション分割を正当化するのに十分な頻度でアクセスされることはありません 。より露骨なことを心配する別のパフォーマンスメトリックがあるかもしれません( XFSでの内部デフラグ 、ext3対ext4など)。また、使用しているストレージエンジンについても考慮する必要があります。

  • クラスタ化されたインデックスを管理する必要があるため、InnoDBのインデックス作成はMyISAMと比較すると少し厄介です
  • InnoDBは、ibdata1および現在のログファイル(ib_logfile0またはib_logfile1)にデータを二重に書き込みます
6
RolandoMySQLDBA