シングルパートインデックスでは、インデックス値インターバルは
WHERE
節内の対応する状態で表現されます。よって「インターバル」よりもrange
状態が使用されます。
シングルパートインデックスのための range 状態の定義は次のとおりです。
BTREE
インデックスと
HASH
インデックスでは、=
、<=>
、IN()
、IS
NULL
、または
IS NOT NULL
演算子を使用する場合、キーパートと定数値の比較はレンジ条件です。
BTREE
インデックスでは、>
、<
、>=
、<=
、BETWEEN
、!=
、または
<>
演算子を使用する場合、あるいは、LIKE
比較を使用する場合で
LIKE
の引数がワイルドカード文字以外で始まる定数文字列のとき、キーパートと定数値の比較はレンジ条件です。
全インデックスの種類にとって、OR
または AND
で結合されたマルチレンジ状態は、あるレンジ状態を形成します。
先の説明の 「定数値」は次の 1 つを意味しています。
クエリー文字列の定数
同じ結合の
const
または
system
テーブルのカラム
相関しないサブクエリーの結果
以前の型のサブ表現からのみ生成された表現
ここに WHERE
節内でレンジ状態のクエリーの例を次に示します。
SELECT * FROM t1 WHEREkey_col
> 1 ANDkey_col
< 10; SELECT * FROM t1 WHEREkey_col
= 1 ORkey_col
IN (15,18,20); SELECT * FROM t1 WHEREkey_col
LIKE 'ab%' ORkey_col
BETWEEN 'bar' AND 'foo';
非定数値が定数伝播フェーズ中に定数に変換されることに留意してください。
MySQL は WHERE
節から、各インデックスよりレンジ状態を抽出しようとします。抽出プロセスの最中、レンジ状態を生成することができない状態は破棄され、重複するレンジを生成する状態は結合され、そして空のレンジを生成する状態は取り除かれます。
key1
がインデックスカラムで
nonkey
がインデックスカラムでない、下記のステートメントを考慮に入れてください。
SELECT * FROM t1 WHERE (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR (key1 < 'bar' AND nonkey = 4) OR (key1 < 'uux' AND key1 > 'z');
key1
の抽出プロセスは次のとおりです。
オリジナルの
WHERE
節で始めてください。
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR (key1 < 'bar' AND nonkey = 4) OR (key1 < 'uux' AND key1 > 'z')
nonkey = 4
と
key1 LIKE
'%b'
はレンジスキャンに使用できませんので、取り除いてください。TRUE
と置き換えることが、正しく取り除く方法です。こうすることによって、レンジスキャン中に適合する行を見落としません。TRUE
で置き換えたとき、次になります。
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR (key1 < 'bar' AND TRUE) OR (key1 < 'uux' AND key1 > 'z')
常に真か偽のコラップス状態
(key1 LIKE 'abcde%' OR
TRUE)
は常に真です
(key1 < 'uux' AND key1
> 'z')
は常に偽です
定数でこれらの状態を置き換えると、次になります。
(key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)
不必要な TRUE
と
FALSE
定数を取り除くことで、次になります。
(key1 < 'abc') OR (key1 < 'bar')
重複するインターバルを 1 つに結合することでレンジスキャンで使用できる最終状態が生成されます。
(key1 < 'bar')
一般的にレンジスキャンで使用される状態は
(そして前の例で説明したとおり)、WHERE
節よりも制限されません。MySQL
はレンジ条件を満たすが、WHERE
節を完全に満たさない行にフィルタをかけるために追加で確認を行います。
レンジ条件抽出アルゴリズムは任意のデプスの入れ子
AND
/OR
生成子を取り扱うことができ、その出力は
WHERE
節内でどの順序で条件が現れるかに影響されません。
現在、MySQL では、空間インデックスの
range
アクセスメソッドで複数レンジのマージはサポートされていません。この制限を回避するには、UNION
で同じ
SELECT
ステートメントを使用します。ただし、各空間述語は、それぞれ異なる
SELECT
に含めます。