数百万行のテーブルがあり、その中に3つの整数変数があります。x、y、zに対して、SELECTで検索を実行します... WHERE x = a and y = b and z = c
どちらがより速く/より効率的でしょうか?
3つのフィールドを個別の文字列列「x_y_z」(例:1231_3242_6864)に結合し、インデックスを作成します
3つの整数に対して3列のインデックスを作成しますか?
数百万行のテーブルがあり、その中に3つの整数変数があります。x、y、zに対して、SELECTで検索を実行します... WHERE x = a and y = b and z = c
どちらがより速く/より効率的でしょうか?
3つのフィールドを個別の文字列列「x_y_z」(例:1231_3242_6864)に結合し、インデックスを作成します
3つの整数に対して3列のインデックスを作成しますか?
いいえ、最悪です。文字列の比較ははるかに遅くなります。最終的には(本当に必要な場合はお勧めしません)、3つの整数を1つの整数に組み合わせることができますが、それらが適合する場合に限ります。
ただし、インデックスを解決するための最も簡単な問題は、x、y、zに複合インデックスを作成することです。
カバーするインデックスがあり、3つの数値すべてが常に提供されるため、インデックスの順序に関係がない場合(これは文字列バージョンでも問題になることに注意してください)、3つのintの複合インデックスを使用します。
3つのintは占有するスペースが少なくなり、ページごとにより多くの行が収まるようになります。これにより、通常、読み取り時にインデックスがより効率的になります。また、99999の5バイトの文字列(+/-〜2 ^ 31の場合は4バイト)と比較して、その整数にははるかに多くのヘッドルームがあります。
データベースクエリでは効率の大きさを判断するのは難しいでしょうが、これらを組み立ててデータを入力する必要があることも忘れないでください。MySQLでそれを実行する方法や場所がわからない-SQLServerは計算列を永続化しており、文字列バージョンにコミットする場合に適した設計上の選択となる可能性があります。
確かに、整数を文字列に変換して、結合を実行する前にその場で連結したくないでしょう。
手元の議論に関連する他のいくつかの質問があります:
INTとVARCHARの主キーの間に実際のパフォーマンスの違いはありますか?
複合インデックスに関する質問から、回答の1つは、 x、y、およびzがそれらの間で一意である傾向がある場合(つまり、ほとんどのx値が互いに異なる場合など)、そうではないことを示しているようです。とにかくパフォーマンスを大幅に向上させます。しかし、もしそうなら、複合インデックスが進むべき道のようです。
本当に自分でベンチマークする必要があると思います(特定のデータに対する特定のクエリのパフォーマンスを決定する他の要因が確かにあります)が、@mb14によって提案された複合3列インデックスを使用するというアイデアに加えて。あなたはこれを試すことができます:
次のように、テーブルに新しい列を作成します。
xyzcomposite BINARY(16)
次に、この列にインデックスを作成します。
挿入では、文字列 "x_y_z"に連結するための追加の手順を実行してから、次のように挿入する必要があります。
INSERT INTO yourtable (...,xyzcomposite) VALUES (...,UNHEX(MD5('the_xyz_concat')));
もちろん、selectステートメントの前にもハッシュアルゴリズムを実行する必要があります。
set @xyz = UNHEX(MD5('x_y_z'));
select * from yourtable where xyzcomposite = @xyz
このオーバーヘッドの合計が、この1列のインデックスと3列のインデックスだけをインデックス付けする必要がある場合に見られるパフォーマンスの向上に見合うかどうかはわかりません。私が言ったように、あなたはあなたのテーブルとあなたのデータに対してそれをベンチマークしなければならないでしょう。
編集:このアプローチの利点は、任意のサイズのx、y、zの数値に対して機能することです。