鉴于以下内容 -
drop table if exists learning_indexes;
create table learning_indexes (
id INT NOT NULL,
col1 CHAR(30),
col2 CHAR(30),
col3 CHAR(30),
PRIMARY KEY (id),
index idx_col1 (col1),
index idx_col1_col2 (col1,col2)
);
explain
select
col1,col2
from
learning_indexes
where
col1 = 'FOO'
and col2 = 'BAR'
为什么MySQL在idx_col1_col2上选择idx_col1?
+----+-------------+------------------+------+------------------------+----------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+------+------------------------+----------+---------+-------+------+-------------+
| 1 | SIMPLE | learning_indexes | ref | idx_col1,idx_col1_col2 | idx_col1 | 91 | const | 1 | Using where |
+----+-------------+------------------+------+------------------------+----------+---------+-------+------+-------------+
这是我的版本信息 -
+-------------------------+---------------------+
| Variable_name | Value |
+-------------------------+---------------------+
| innodb_version | 1.1.8 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 5.5.29 |
| version_comment | Source distribution |
| version_compile_machine | i386 |
| version_compile_os | osx10.7 |
+-------------------------+---------------------+
答案 0 :(得分:0)
我无法在这里解释你的情况,但有时MySQL只选择“错误的”索引。也许数据库足够小,以至于它知道在这种情况下它没有任何区别。
此查询非常简单,应该了解哪个索引最合适。
我可以根据经验说,当查询变得越来越复杂,特别是当表格变得非常大时,MySQL有时会(随机?)决定选择另一个索引并继续使用,然后查询可以从0.01秒到100秒+秒,所以如果您知道哪个索引是正确的索引,请使用FORCE INDEX()。即使您使用USE INDEX(),MySQL有时会选择另一个索引,其查询速度会有各种去除结果。
答案 1 :(得分:0)
我同意Floaf认为MySQL有时会选择错误的索引,但我不认为这是这种情况。 MySQL将行数和数据结构包含在决定选择哪个索引中。
对于像这样的一个相当简单的查询,如果表包含少于约100行或甚至为空,MySQL根本不会使用任何索引。扫描所有表行比使用索引计算成本更低。在您的解释计划中,您可以看到“key”列表示idx_col1,但“Extra”列没有说“使用索引”。
如果表包含超过100行,MySQL将开始使用idx_col1。解释计划会告诉你这个。只有当col1中实际包含字符串'FOO'的行数超过100行时,MySQL才会注意到使用idx_col1不会减少临时结果集,因为它必须扫描剩余的100行以获取值' BAR'在col2中。因此,它将切换到idx_col1_col2。
我不完全确定MySQL如何快速决定使用哪个索引,但我认为它与启发式和索引中各行的基数有关,即索引行的“选择性”如何。