ホームページ > データベース > mysql チュートリアル > 範囲クエリを使用する複数列インデックスでは、カーディナリティの高い列を最初に置く必要がありますか?

範囲クエリを使用する複数列インデックスでは、カーディナリティの高い列を最初に置く必要がありますか?

Patricia Arquette
リリース: 2024-12-02 11:34:13
オリジナル
662 人が閲覧しました

Should Higher Cardinality Columns Come First in Multi-Column Indexes with Range Queries?

範囲が含まれる場合は、最初にカーディナリティの高い列でインデックスを作成します

次のテーブルを考えてみましょう。

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`),          -- This?
  KEY `ef` (`ext`,`filetime`)           -- or This?
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
ログイン後にコピー

100 万行、filetime のカーディナリティが高く、ext のカーディナリティが低い、 fe と ef のどちらのインデックスがより有利であるかという疑問が生じます。

Force Index と EXPLAIN による分析

FORCE INDEX を使用して両方のインデックスをテストすると、明らかな違いが明らかになりますパフォーマンス:

-- Forcing the range on filetime first
mysql> EXPLAIN SELECT COUNT(*), AVG(fsize)
    FROM files FORCE INDEX(fe)
    WHERE ext = 'gif' AND filetime >= '2015-01-01'
                      AND filetime <  '2015-01-01' + INTERVAL 1 MONTH;
ログイン後にコピー
-- Forcing the low-cardinality ext first
mysql> EXPLAIN SELECT COUNT(*), AVG(fsize)
    FROM files FORCE INDEX(ef)
    WHERE ext = 'gif' AND filetime >= '2015-01-01'
                      AND filetime <  '2015-01-01' + INTERVAL 1 MONTH;
ログイン後にコピー

EXPLAIN 出力は、ef が

オプティマイザー トレースによる分析

オプティマイザー トレースは ef:

"potential_range_indices": [
    ...
    {
        "index": "fe",
        "usable": true,
        ...
    },
    {
        "index": "ef",
        "usable": true,
        ...
    }
],
"analyzing_range_alternatives": {
    "range_scan_alternatives": [
        {
            "index": "fe",
            "ranges": [
                "2015-01-01 00:00:00 <= filetime < 2015-02-01 00:00:00"
            ],
            "cost": 20022,   -- Higher cost
        },
        {
            "index": "ef",
            "ranges": [
                "gif <= ext <= gif AND 2015-01-01 00:00:00 <= filetime < 2015-02-01 00:00:00"
            ],
            "cost": 646.61,  -- Lower cost
        }
    ],
}
ログイン後にコピー
トレースにより、ef がインデックスの両方の列を使用できるため、より効率的な検索が行われることがわかります。さらに、オプティマイザーは最初の 'range' 列のみを検査し、ext のカーディナリティは無関係であることを強調しています。

結論

分析に基づくと、次のようになります。複数のインデックス付き列を含む範囲クエリを処理する場合、列の順序は次のとおりである必要があることを明確にします。 be:

    基数に関係なく、等価テストに関係する列を最初に配置します。
  • 範囲に関係する他の列は、等価列の後に配置する必要があります。
このアプローチにより、インデックスが最も効果的に使用され、最適なクエリ パフォーマンスが得られます。

以上が範囲クエリを使用する複数列インデックスでは、カーディナリティの高い列を最初に置く必要がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート