web-dev-qa-db-ja.com

in演算子を使用すると、インデックスの使用に影響がありますか?

in演算子を使用すると、インデックスの使用に影響がありますか?たとえば、WHERE id IN (10)がオプティマイザにインデックスを無視させる可能性はありますか?

具体的には、StackOverflowから この答え を理解しようとしています。質問では、(MySQLで)インデックスが使用されていない理由を尋ね、答えは、値が1つだけのinの使用が原因である可能性があることを示唆しています。たとえば、WHERE id IN (10)はインデックスを無視する可能性がありますが、WHERE id=10で結構です。

私はGoogleをざっと見回して、いくつかのMySQLドキュメントをざっと調べましたが、インデックスを使用するオプティマイザの決定に影響を与えるinへの参照は見つかりません。単一の値でも複数の値でもありません。

IN値が、比較している列と同じデータ型であると仮定すると、それらはインデックスの使用に影響を与えることができますか?

私がリンクした質問はMySQLに関するものでしたが、他のDBで作業しているので、これがインデックスについて普遍的なことなのか、それともMySQLの癖なのかを知りたいと思います。

5
RToyo

それがMySQLで発生する場合、それはMySQLの癖です。他のデータベースについても尋ねたので、私は自分のpostgresデータベースでテストすることにしました。 7000万行を少し超えるテーブルでは、次の2つのクエリに対して(インデックスを使用して)まったく同じ説明が生成されます。

explain select * from myschema.my_list where my_column in (232);
explain select * from myschema.my_list where my_column = 232;

それは:

'Bitmap Heap Scan on my_list  (cost=68093.11..4109456.90 rows=1656844 width=994)'
'  Recheck Cond: (my_column = 232)'
'  ->  Bitmap Index Scan on my_list_2  (cost=0.00..67678.90 rows=1656844 width=0)'
'        Index Cond: (my_column = 232)'

リストに複数の要素を追加するまで、分岐しません。

 explain select * from myschema.my_list where my_column in (232,79);
 explain select * from myschema.my_list where my_column = 232 or my_column = 79;

(それぞれ):

'Bitmap Heap Scan on my_list  (cost=172208.28..7050980.15 rows=4290987 width=994)'
'  Recheck Cond: (my_column = ANY ('{232,79}'::integer[]))'
'  ->  Bitmap Index Scan on my_list_2  (cost=0.00..171135.53 rows=4290987 width=0)'
'        Index Cond: (my_column = ANY ('{232,79}'::integer[]))'

'Bitmap Heap Scan on my_list  (cost=177390.73..7066890.07 rows=4230402 width=994)'
'  Recheck Cond: ((my_column = 232) OR (my_column = 79))'
'  ->  BitmapOr  (cost=177390.73..177390.73 rows=4290987 width=0)'
'        ->  Bitmap Index Scan on my_list_2  (cost=0.00..67678.90 rows=1656844 width=0)'
'              Index Cond: (my_column = 232)'
'        ->  Bitmap Index Scan on my_list_2  (cost=0.00..107596.63 rows=2634142 width=0)'
'              Index Cond: (my_column = 79)'

私は彼の答えを一粒の塩でとるでしょう。

6
indiri

INを1つのアイテムにすると、オプティマイザーの最初の「ステップ」の1つとして=に変わります。

あなたの参照 https://stackoverflow.com/questions/45989068/why-isnt-mysql-using-the-index-on-our-table ( "this answer")isnotINのインデックスの使用の失敗について;それよりも複雑です。

そして、あなたの質問はあなたが理解するよりも複雑です。

オプティマイザーがINのインデックスを使用しない理由はたくさんあります。ただし、[INを使用ではなくインデックスを使用しないに重点を置く必要があります。

特定の例がある場合は、それについて説明します。

さらに

Operator_traceから、おそらく"expanded_query"のようなものを含む「ステップ」を見ることができます: "/select#1/ select tbl.col2 AS col2 from tbl where(tbl.col1 = 123456) "は「展開」 "of... where col1 IN(123456)

2
Rick James