我有个问题:
SELECT *
FROM table1
WHERE foo IN (1,2,3,4) AND bar = 123;
我有3个索引:
ALTER TABLE table1 ADD INDEX IDX_foo (foo);
ALTER TABLE table1 ADD INDEX IDX_bar (bar);
ALTER TABLE table1 ADD INDEX IDX_foo_bar (foo, bar);
当我尝试的时候 EXPLAIN
有了这个问题, IDX_bar
我不明白为什么。所以我的问题是:
为什么是 IDX_bar
选择但不是 IDX_foo
或者 IDX_foo_bar
?
mysql是否根据当时的数据选择不同的索引?
我应该只有 IDX_bar
把另外两个拿走?
1条答案
按热度按时间3wabscal1#
使用
INDEX(bar, foo)
. 也就是说,把那个和=
第一。老版本的mysql没有那么聪明。对于所有版本的mysql,上面的索引可能是最好的,或者至少与最好的一致。
关于构建mysql索引的一般课程:http://mysql.rjweb.org/doc.php/index_cookbook_mysql
您的具体问题:
为什么选择了idx\u bar而不是idx\u foo或idx\u foo\u bar?——
=
是优化的最佳选择。mysql是否根据当时的数据选择不同的索引?--是的(但不经常)。例如,如果
bar
不经常123
,任何以bar
可能有用。如果经常123
,那么在索引和数据之间来回跳转的成本可能比索引带来的好处更高(截止值各不相同,但通常在20%左右。)我是否应该只使用idxèU条并删除其他两个?--扔掉你的3,留下我的。但是,其他一些查询可能会从您的查询中受益。
注:
INDEX(bar)
是多余的,如果你有INDEX(bar, foo)
; 摆脱前者。(我在这里说的大部分内容都在这个链接中。)