0

比較的大きなテーブル(約2,000万行)で次のクエリを使用しています。

SELECT 
    MAX(`col_1`) 
FROM `table` 
WHERE  
    col_2 = X AND
    col_3 = Y AND
    col_4 = Z

列col_2、col_3、col_4に結合されたインデックスがあり、col_1に別のインデックスがありますが、クエリは、パーツがない同じクエリよりも桁違いに遅くなりますWHERE

インデックスを使用して、このパフォーマンスを向上させるにはどうすればよいですか?

4

2 に答える 2

1

4番目の位置でインデックスcol_1を作成してみることができますが、テーブルの構造(つまり、単一行の重み)に大きく依存します。で計算する場合MAXcol_1なしWHEREで、情報はインデックスを介してすぐに利用できます(いわば、常に左を維持しながら歩くだけです)。

を追加するWHEREと、そうではなくなります。クエリはすでに最適化されている可能性があります。X、Y、Zのタイプと分布を知ることにより、(おそらく)さらなる改善が行われる可能性があります。

(ばかげた例:と言うと、col_2( -255、+ 255)の範囲にあることがわかっています。次に、その上に非正規化された列を保持してインデックスを追加することを考えることができます。おそらく、そのインデックスに基づいてクラスタリングすることもできます。これ結果が適度に小さいデータ型の単射関数を見つけることができ、X、Y、およびZに対して「正確な」クエリを実行することが多い場合、つまり何も実行しない場合は価値があります。col_3col_4(((col_1+255)*512+(col_2+255))*512+(col_3+255))col_1WHERE col_2 BETWEEN X1 AND X2

于 2012-08-30T17:45:25.217 に答える
1

MySQLがインデックスを使用する方法で文書化されているように:

MySQLは、これらの操作にインデックスを使用します。

[ deletia ]

  • 特定のインデックス付き列のMIN()or値を検索します。これは、インデックスで以前に発生したすべての主要部分で使用しているかどうかをチェックするプリプロセッサによって最適化されます。この場合、MySQLはor式ごとに単一のキールックアップを実行し、それを定数に置き換えます。すべての式が定数に置き換えられると、クエリは一度に返されます。例えば:MAX()key_colWHERE key_part_N = constantkey_colMIN()MAX()

    SELECT MIN(key_part2)、MAX(key_part2)
    FROM tbl_name WHERE key_part1 = 10;

col_1したがって、MySQLは、フィルターを適用するときに検索するために定義した単純なインデックスを使用できません。代わりに、一致するすべての行をスキャンする必要があります(ただし、その単純なインデックスで並べ替えることによりMAX(col_1)、降順でスキャンできます)。クエリの出力col_1によって表示されます。EXPLAIN

にインデックスを使用する必要があります(col_2, col_3, col_4, col_1)

于 2012-08-30T17:57:34.673 に答える