web-dev-qa-db-ja.com

パーティション化は、主キーによる検索と挿入/更新に役立ちますか?

MariaDB 10.1とデフォルトのInnoDBストレージストレージを使用しており、現在数千万から1億行のテーブルがいくつかあります。これらのテーブルは、月に数百万ずつ増え続け、ほとんどがキャッシュです。

それらには、単一列の主キー(BIGINT)または複合主キー(2つのBIGINT列)があり、AUTO_INCREMENTがないため、常に主キーで挿入、選択、または更新します。また、主キーによる多数の結合を行うか、WHERE PK IN (1, 2, 3, 4...)を選択します。

また、これらのテーブルは1時間あたり多数の更新を受信します。通常、一度に5000または10000のバッチで更新します。これらのテーブルの一部では、選択よりも多くの挿入と更新があります。

3つの質問があります。

  1. 1行を返すPKによる単純な選択(_SELECT x, y FROM table WHERE pk = 123_)は、パーティション分割のパフォーマンスに実際の違いがないように思えます。そうですか?

  2. WHERE PK IN(SELECT PK FROM ...)としての結合または選択についてはどうですか?パーティション化されたテーブルを結合するスキャンは、単一のテーブルよりも多くなりますか?

  3. 私は通常、以下を使用して多数の同時バッチを実行することを考慮します(複数のサーバーが同時にデータを送信する場合があります)

    • INSERT INTO X VALUES (1, 'A'), (2, 'B'), ... ON DUPLICATE KEY UPDATE ...または

    • REPLACE INTO X VALUES(1, 'A'), (2, 'B'),...

パーティション化は、たとえば複数のパーティションに同時に影響を与えることができるなど、同時挿入と更新に役立ちますか?

前もって感謝します。

5
Natan

あなたの質問

Q1:PKがパーティションキーの場合、パーティションキーの「ポイントクエリ」(_WHERE PK = constant_)は「プルーニング」を実行し、(うまくいけば)インデックスを使用します見つかった単一のパーティションで。適切なインデックスを持つ単純なテーブルを作成すること以上の改善はありません。
Q1:PKが_PRIMARY KEY_であるが、パーティションキーがではない場合、クエリを開き、すべてのパーティションを調べて行を見つける必要があります。したがって、遅くなります。

Q2:一般にIN ( SELECT ... )のパフォーマンスは低く、very場合によってはパフォーマンスが低いため、回避する必要があります。代わりにJOINを使用してください。パーティション化の場合、「プルーニング」はおそらく使用されません。したがって遅い。

Q3:INSERTは関係なく、ほぼ同じ速度になる場合があります。プレーンテーブルは、複雑さが少ないため、高速になる可能性があります
Q3:REPLACEDELETE + INSERTです。 _INSERT ... ON DUPLICATE KEY UPDATE ..._は通常より良い構成です。適用されるかどうかを確認します。しかし、やはり、パフォーマンスの向上はありません。

[〜#〜] in [〜#〜]

WHERE PK IN (1, 2, 3, 4...)-リストが「短い」場合は、パーティション・プルーニングを使用すると聞きました。または、リストが長い場合は剪定をスキップします。どちらの場合でも、PKのインデックスを持つ単純なテーブルは少なくとも同じくらい高速になります。

剪定

この方法でプルーニングを考えてください。最初にパーティション(「サブテーブル」のように機能する)を見つけ、次にインデックス(使用可能な場合)を使用して目的の行にドリルダウンする必要があります。パーティション化しない場合、プルーニングステップはスキップされます。しかし、BTreeインデックスは少し深いです。したがって、これはトレードオフです。

注:これは多くの場合、パーティションテーブルと同等の非パーティションテーブルの最適なインデックスセットが異なることを意味します。

ケース3

「テーブルのインデックスが大きすぎてキャッシュできませんが、1つのパーティションのインデックスはキャッシュ可能です」という警告は、状況に当てはまらないようです。ケース3は、ほとんどのアクティビティが最新のパーティション(およびPARTITION BY RANGE(TO_DAYS(...)))にあり、そのパーティションがbuffer_poolに収まるが、テーブル全体が収まらない時系列から発生しました。

(つまり、ケース3の関連性については、ジャーワッドではなくナタンに同意します。)

BY HASH

_BY HASH_-役に立たない。 (リンクから:「PARTITION BY RANGEが唯一の便利な方法です。」)(または、少なくとも、パフォーマンスが向上するハッシュの使用例はまだ見ていません。)

摂取

月あたり数百万の成長」それはあまり速くありません。 「日あたり数百万の増加」は困難になり始めます。その時点で私はあなたを私の 高速取り込みブログに向けます。 。たとえそうであっても、そこからヒントを1つ取るかもしれません-変更を一時テーブルにロードし、それからinsert/replace/iodku/update/etcをそれから「実際の」テーブルに実行します。

1
Rick James