2


1

主キークエリ用の大規模DBの最適化

あなたが非常に大きなデータベースを持っていて、単純化するためにそれがあなたが一つの(そしてただ一つの)主キーフィールドであなたのルックアップをすることになる一つの主要なテーブルから成ると仮定しなさい

すべての検索が基本的に `SELECT * FROM table_name WHERE pk = someKeyValue`になるという事実を考えると、このデータベースを最速の検索に最適化するための最善の方法は何ですか?

*編集:*ほんの少しの詳細 - INSERT`と UPDATE`はあまり頻繁ではないので、より良いルックアップパフォーマンスを達成するためにパフォーマンスを犠牲にしても構わない。

また、クラスタリングが進むべき道であるように思われます。 この方法で達成できるパフォーマンスの向上の例はありますか。 そして、これはどのように正確に行われているのでしょうか。

7 Answer


4


主キーがクラスタ化されている場合は、それ以上速くなることはありません。

それがクラスタ化されておらず、テーブル内の列数が比較的少ない場合は、理論的にはカバーするインデックスを作成してクエリを高速化することができます。 しかし、そうすると、これは、非クラスタ化主キーを持つことによって得られたであろう挿入/更新のパフォーマンスの向上を否定します。

あなたの主キーが常に増加している分野であるなら(例えば SQL ServerのID、またはOracleのシーケンスから生成された場合は、クラスタ化された主キーに問題はありません。


1


1つできることは、主キーをクラスタ化することです。これにより、実際のデータがディスク上で物理的に順序付けられ、クエリが高速になります。

挿入が遅いことも意味しますが、挿入よりもはるかに頻繁に選択する場合は、これは問題になりません。


1


MySQLを使用している場合は、(キャッシュ値を調整する以外に)いくつか追加のことを実行できます。 テーブルエンジンが要因になる可能性があります。たとえば、MyISAMはInnoDBよりもSELECTのほうが速いと広く考えられています。 このテーブルが主にルックアップテーブルで、MySQLを使用している場合は、それを実行するのが良いかもしれません。 (InnoDBは平均的にかなり良いです; MyISAMよりも書き込みに関しては優れています、そしてまた、InnoDBは決して修理される必要はありません。)


1


私は上で提案されたすべてに2つのオプションを追加しなければなりません(私はdwcの答えが好きです)。 テーブルが本当に大きい場合は、パーティション化を検討する必要があります。

まず、水平分割(特に、DBでI / Oがボトルネックになっている場合)。 いくつかのファイルグループを作成し、それらを異なるハードドライブに配置します。 次に、Partition Function、Partition Schemeを作成して、テーブルを分割し、テーブルの一部を別々のHDに配置します(F:ドライブには1〜4999999行、G:ドライブには500000〜999999など)。

第二に、垂直分割。 これは、ほとんどのクエリで列セット(*以外)を選択した場合に機能します。 この場合、テーブル内の列を2つのグループに分けます。まず、すべてのクエリに必要なフィールド。第二に、あなたがめったに必要としないフィールドです。 同じ主キーを持つ2つのテーブルを作成します。 両方のテーブルのカラムが必要な場合は、主キーにJOINを使用してください。

(この回答はSQL Server 2005/2008に関するものです。)


0


すべてのクエリがPKに基づいて行われる場合は、PKにインデックスが設定されていてもすでにインデックスが作成されているため、追加のメリットはありません。

編集:私が提案するであろう他の唯一の可能なことはあなたのテーブルを正規化することを見ることです(それがオプションまたは必要性さえあるならば)。 アイテムを他のテーブルに分割することで、各クエリで引き戻されているものを絞り込み、結合を使用して必要に応じて使用頻度の低いアイテムのみを引き出すことができます。

「単一のテーブルを持つ非常に大規模なデータベース」という限られた説明に基づいて、実際にどのような種類のデータをフィールドに格納しているのかを見ずに最適化する簡単で明白な方法を見つけるのは困難です。


0


  • あなたのPKオーダーが広告掲載オーダーと一致する場合 時間またはID /自動インクリメント、それからそれをクラスタ化します。 これにより、挿入時のディスクとキャッシュのスラッシングが減少し、検索に使用するリソースが増えます。

  • テーブルのページサイズを調整して、レコードサイズの正確な倍数になるようにします。 これには、特定のデータベースソフトウェアの詳細、およびレコード/インデックスのオーバーヘッドなどに関する詳細な知識が必要です。

  • 実用的な場合は、可変サイズではなく、すべての列に固定サイズを使用してください。

  • インデックスファイルやトランザクションログファイルを別のボリュームに配置することを検討してください。

  • ソフトウェアとハ​​ードウェアが使用できるだけのRAMを取り付けます。


0


Oracleを使用していたなら、3つのアプローチをベンチマークすることをお勧めします。

  1. 主キーインデックスを持つヒープテーブル

  2. 索引構成表

  3. 単一表ハッシュ・クラスター

1は非常に一般的なアプローチを表します - 実際には最も一般的な分母ですが、完全にキャッシュされていない場合、それらのうちの1つがテーブルの物理的読み取りの可能性があります。

2を指定すると、プローブを別のテーブルセグメントに避けることで論理的な読み取りの1つを節約できますが、IOTセグメントはインデックスよりも大きく、キャッシュしにくいため、物理的な読み取りを節約できない場合があります。

3を指定すると、単一の論理読み取りで行が取得される可能性がありますが、テーブル全体をキャッシュに入れていない限り、これはおそらく物理読み取りに変換されます。

ベンチマークを強くお勧めします。