使用 in 运算符会影响索引的使用吗?

RTo*_*oyo 5 mysql index execution-plan

使用in运算符会影响索引的使用吗?例如,是否有可能WHERE id IN (10)导致优化器忽略索引?

具体来说,我试图从 StackOverflow理解这个答案。问题询问为什么没有使用索引(在 MySQL 中),答案表明这可能是由于in仅使用了一个值。例如,WHERE id IN (10)可能会忽略索引,而WHERE id=10会很好。

我在 Google 上短暂浏览了一下,浏览了一些 MySQL 文档,但找不到任何in影响优化器使用索引的决定的参考。既不具有单个值,也不具有多个值。

假设这些IN值与它们正在比较的列具有相同的数据类型,它们会影响索引使用吗?

我链接到的问题是针对 MySQL,但我在其他数据库中工作,所以我很想知道这是否是关于索引的普遍注意事项,或者它是否是 MySQL 的一个怪癖。

ind*_*iri 6

如果这种情况发生在 MySQL 中,那么它就是 MySQL 的一个怪癖。由于您也询问了其他数据库,因此我决定在我的 postgres 数据库上对其进行测试。在一个略多于 7000 万行的表上,它为以下两个查询(带有索引)生成完全相同的解释:

explain select * from myschema.my_list where my_column in (232);
explain select * from myschema.my_list where my_column = 232;
Run Code Online (Sandbox Code Playgroud)

即:

'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)'
Run Code Online (Sandbox Code Playgroud)

在我在列表中添加多个元素之前,它不会发散:

 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;
Run Code Online (Sandbox Code Playgroud)

这是(分别):

'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)'
Run Code Online (Sandbox Code Playgroud)

我对他的回答持保留态度。