ホームページ >データベース >mysql チュートリアル >範囲クエリに最適な複合インデックスはどれですか: 高カーディナリティ列と低カーディナリティ列?

範囲クエリに最適な複合インデックスはどれですか: 高カーディナリティ列と低カーディナリティ列?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-24 14:10:47254ブラウズ

Which Composite Index is Optimal for Range Queries: High vs. Low Cardinality Columns?

範囲クエリを使用した複合インデックスでの高カーディナリティ列の配置

範囲条件を含む複合インデックスを使用してテーブルをクエリする場合、インデックス内の列はパフォーマンスに大きな影響を与える可能性があります。

主キーを持つテーブル ファイルを検討してください。 (did, filename) と 2 つの複合インデックス: INDEX(filetime, ext) と INDEX(ext, filetime)。どちらのインデックスにも、ext よりもカーディナリティが高い filetime 列が含まれています。

クエリ:

WHERE ext = '...'
  AND filetime BETWEEN ... AND ...

では、ext と filetime の両方に基づいてデータにアクセスする必要があります。このようなクエリにはどのインデックスが最適ですか?

分析

最適なインデックスを決定するには、FORCE INDEX を使用して実行計画を調べることができます。

-- Force range on filetime first
FORCE INDEX(fe) SELECT COUNT(*), AVG(fsize)
FROM files
WHERE ext = 'gif'
  AND filetime >= '2015-01-01'
  AND filetime < '2015-01-01' + INTERVAL 1 MONTH;

-- Force low-cardinality ext first
FORCE INDEX(ef) SELECT COUNT(*), AVG(fsize)
FROM files
WHERE ext = 'gif'
  AND filetime >= '2015-01-01'
  AND filetime < '2015-01-01' + INTERVAL 1 MONTH;

出力は、INDEX(ext, filetime) (ef) の行数が大幅に少ないことを示しています。

オプティマイザー トレース

オプティマイザーの動作をさらに分析するには、オプティマイザー トレースを使用できます。

SELECT explain_format = 'JSON';

SELECT COUNT(*), AVG(fsize)
FROM files
WHERE ext = 'gif'
  AND filetime >= '2015-01-01'
  AND filetime < '2015-01-01' + INTERVAL 1 MONTH;

トレースにより次のことがわかります。オプティマイザはインデックスの両方の列をフィルタリングとフェッチに使用できるため、INDEX(ext, filetime) を選択します。 データ。対照的に、INDEX(filetime, ext) は、フィルター処理に最初の列 (filetime) のみを使用できます。

結論

分析に基づいて、次の結論が得られます。描画:

  • 範囲クエリで使用される複合インデックスの場合、等価述語に含まれる列(この場合は ext) はインデックス定義の最初に配置する必要があります。
  • インデックス内の列が WHERE 句で使用される順序に従って並べ替えられると、クエリのパフォーマンスが向上します。
  • カーディナリティだけでは、最適なインデックスを決定する決定的な要素ではありません。範囲列のカーディナリティが高いが、等価列が等価述語に関与しているシナリオでは、等価列を最初に配置するとパフォーマンスが向上します。

以上が範囲クエリに最適な複合インデックスはどれですか: 高カーディナリティ列と低カーディナリティ列?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。