4

「取引」に関するデータを保持するテーブルがあります。取引はクローズまたはオープンのいずれかであり、「is_closed」列にそのようにマークされます。(またはもちろん、索引付けされています)。

約 10,000 の「開いた」行と 10,000,000 の「閉じた」行があります。各「開いている」行は、約 1 秒に 1 回更新されます。(インデックス化されていないフィールドのみがここで更新されます)。行が「クローズ」されると、再び更新されることはありません。(読むだけ)。

開いている行と閉じている行の両方を処理する選択を実行する必要はないので、問題は次のとおりです。テーブルを同じ構造の 2 つのテーブル (開いたテーブルと閉じたテーブル) に分割する必要がありますか?

単一のテーブルの短所は、毎秒 10,000,000 行のテーブルで更新を実行することです。2 つのテーブルの短所は、一種のコードの重複があり、「取引」を成立させるときに、一方のテーブルからそれらを削除し、もう一方のテーブルに追加する必要があることです。

4

5 に答える 5

1

それらを 2 つの表に分けます。短所はありません:

  • 2 つのテーブルの短所は、一種のコードの重複があることです。

だから何?コード行を減らすのではなく、パフォーマンスを目標にします。

  • そして、「取引」を閉じるときは、一方のテーブルからそれらを削除し、もう一方のテーブルに追加する必要があります。

さらに数行のコード。一部の UPDATE プロシージャは、INSERT/DELETE プロシージャに変換されます。


長所は次のとおりです。

  • 両方のテーブルで、インデックスが 1 つ少なくなります。
  • 複合インデックス (open/closedフラグを含む) は少し狭くなります。
  • さらに重要なのは、トラフィックが多いテーブル内のすべてのインデックスがはるかに小さくなることです。
于 2012-06-27T16:59:56.070 に答える
1

クローズとオープンの比率が >= 1000 の場合 (前述のとおり)、2 つの異なるテーブルを作成することをお勧めします。

ポリモーフィズムを使用すると、コードの重複を回避できます。AbstractDealという名前で取引の 1 つの抽象基本クラスを作成し、2 つの具象クラスOpenDealおよびCloseDealを拡張できます。これら 2 つの具象クラスをそれぞれテーブルにマップできます。

これがより良い解決策になることを願っています。

于 2012-06-27T14:49:24.693 に答える
1

あなたのようなブール (true と false、または 1 と 0) 列は、状況によっては問題ありませんが、そのような列にインデックスを付けていることに気付いた場合は、おそらく一線を越えています。

値が均等に分散されている場合 (50% が true で 50% が false)、MySQL はインデックスを使用することさえありません (カバー インデックスでない限り)。データセットの大部分が返されるセカンダリ インデックスを介して各行を検索するコストは高くつくため、MySQL は代わりに単純なテーブル スキャンを実行します。

あなたの場合、より小さな分布 (1% false) に対してクエリを実行しているため、MySQL は実際にインデックスを利用する可能性があります。

ただし、使用されていない真の値をインデックスに格納する必要があるのに、インデックスの更新が遅くなり、スペースが無駄になるだけです。

...改訂...

代わりに、インデックスを別のテーブルの形式で外部に格納することを検討してください。次の構造を持つ open_deals という名前のテーブルを追加することを検討してください。ここで、deal_id は、取引と open_deals の両方の主キーです。

deal_id
----------
100
121
135

オープン ディールを取得するには、次の操作を行うだけです。

SELECT deals.*
FROM open_deals
STRAIGHT_JOIN deals
  ON deals.deal_id = open_deals.deal_id

左から右に結合することが常にわかっているため、ストレート結合を使用し、MySQL がそれについて考える必要がないようにします。

open_deals は 1 つのインデックス付き列のみで構成されているため、インデックスはカバリング インデックスとして機能します。適切に構成された強力なサーバーでは、インデックスがメモリに格納されるため、テーブルは非常に高速になります。

結合は、内部的には元のセカンダリ インデックスを使用する場合と似ていますが、未使用の値すべてによるオーバーヘッドはありません。

最高のパフォーマンスを得るには、新しい値が open_deals テーブルの末尾に追加されていることを確認してください。つまり、すべての新しい値が最後の値よりも大きくなる必要がありますが、とにかくそうしています。

取引をオープンに設定するには、それを open_deals テーブルに追加し、クローズとしてマークするには、open_deals テーブルから ID を削除します。

ここでの利点は、テーブル間でレコードを移動する必要がなく、他のインデックスを更新する必要がないことです (InnoDB のクラスター化インデックスではさらに悪いことです)。ここで更新される唯一のインデックスは、open_deals テーブルのかなり小さいインデックスです。

于 2012-06-27T15:54:01.497 に答える
1

状態列ごとにテーブルを分割できると思うので、論理的には1つのテーブルがあります。あなたの場合、リストパーティションが適切なようです。次に、さらに進んで、必要に応じて「閉じた」パーティションをサブパーティション化できます...

于 2012-06-27T14:42:43.953 に答える
0

両方のテーブルが同じテーブルスペースにある限り、テーブルを分割したり分割したりしてもほとんど何も得られません。コードの単純さの利点は、テーブルを 1 つに保持することを強く支持します。

InnoDB は行レベルのロックを行うため、終了した取引が進行中の取引をブロックすることはありません。

于 2012-06-27T14:48:09.270 に答える