MySQLインデックスの範囲抽出 Documentation を行いました。彼らは単一の列のインデックスについて説明しました。複雑なマルチカラム(少なくとも2つ)基準を減らす手順は何ですか?
私が本質的に求めていることは、複雑な述語から範囲間隔を単純化/縮小する方法を説明するアルゴリズムまたは文献がありますか? B-TREEインデックスまたはキー値の順次配置を持つ任意のインデックスを想定しています。
例えば:-
単一列の例
From
(duration > 5 and duration < 10) or (duration < 100)
To
NULL < duration < 100
From
(duration > 5 and duration < 10) or (duration < 100)
To
5 < duration < 10
100 < duration
2つの列の例
From
(duration in (9,10) and service_id > 500)
To
9 <= duration <= 9 AND 500 < service_id
10 <= duration <= 10 AND 500 < service_id
From
(duration in (9,10) and service_id = 500) or (duration = 19 and service_id=570)
To
9 <= duration <= 9 AND 500 <= service_id <= 500
10 <= duration <= 10 AND 500 <= service_id <= 500
19 <= duration <= 19 AND 570 <= service_id <= 570
歴史的に、MySQLは最適ではなくても、関連するアルゴリズムを単純にしてきました。特に、OR
は最適化が不十分です。 5.7と8.0には新しいコードがありますが、例が改善されたかどうかはわかりません。
EXPLAIN FORMAT=JSON
は時々手がかりを与えます。また、「オプティマイザトレース」も参照してください。
サンプルデータがある場合は、ハンドラカウントを使用して、それらが適切に最適化されているかどうかを推測します。 http://mysql.rjweb.org/doc.php/index_cookbook_mysql#handler_counts 。
ただし、MySQLは明らかなインデックスを使用する代わりにテーブルスキャンを実行することが多いことに注意してください。セカンダリインデックスのBTreeとデータを含むBTreeの間でバウンスするコストのため、これは正当です。通常、インデックスの20%以上を変更する必要がある場合は、テーブルスキャンを実行することをお勧めします。 (「20%」はハードコーディングされた数値ではありませんが、使用される「コストベース」モデルの大幅な簡略化です。)
検索する mysql cost based optimization
。このトピックについて書かれた記事がいくつかあります。