ホームページ >データベース >mysql チュートリアル >範囲クエリに対して、高カーディナリティ列と低カーディナリティ列を使用する場合、どちらの MySQL インデックスがより効率的ですか?

範囲クエリに対して、高カーディナリティ列と低カーディナリティ列を使用する場合、どちらの MySQL インデックスがより効率的ですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-29 02:55:14596ブラウズ

Which MySQL Index Is More Efficient for Range Queries: Leading with High or Low Cardinality Column?

範囲クエリのインデックスの最適化

カーディナリティが高い列は、MySQL のインデックスの効率化に貢献します。ただし、範囲クエリの場合は例外が適用されます。

問題ステートメント

次の構造を持つテーブルを考えてみましょう:

CREATE TABLE `files` (
  `did` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `filename` VARBINARY(200) NOT NULL,
  `ext` VARBINARY(5) DEFAULT NULL,
  `fsize` DOUBLE DEFAULT NULL,
  `filetime` DATETIME DEFAULT NULL,
  PRIMARY KEY (`did`,`filename`),
  KEY `fe` (`filetime`,`ext`),          -- Option 1
  KEY `ef` (`ext`,`filetime`)           -- Option 2
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ファイル時間は明確ですが、ext 値の数は限られています (つまり、ファイル時間のカーディナリティが高く、ファイル時間のカーディナリティが低くなります)例)。クエリには、次の条件を持つ両方の列が含まれます:

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

fe と ef のどちらのインデックスがより最適ですか?

答え

驚くべきことに、最初の列が ext であるインデックスは、カーディナリティが低いにもかかわらず、この場合はより効率的です。 query.

説明

MySQL のオプティマイザは、インデックスの代替を分析し、コストが最も低いものを選択します。オプティマイザー トレースを使用すると、この選択の背後にある理由を観察できます。

fe (ファイルタイム ファースト) の場合、MySQL は、範囲条件がオンであっても、'gif' ファイルを見つけるために 16684 行をスキャンする必要があると推定します。 filetime.

ただし、ef (ext first) の場合は、両方のインデックス列を使用して適切な行に迅速にドリルダウンできると推定され、結果は次のようになります。コストはわずか 646.61 円です。 MySQL は、より多くのキー部分を使用でき、検索をより効率的にできるため、このインデックスを選択します。

結論

  • インデックス内の等価テストに関係するカラムを優先します。カーディナリティに関係なく。
  • クエリ プランは最初の「範囲」を超えて拡張されません。
  • このコンテキストでは、カーディナリティは複合インデックスと範囲クエリには無関係です。
  • InnoDB は、フィルタリングに使用されるインデックス列を超えてインデックス列を利用できます (「インデックス条件の使用」)。

以上が範囲クエリに対して、高カーディナリティ列と低カーディナリティ列を使用する場合、どちらの MySQL インデックスがより効率的ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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