当多个可能时,MySQL索引

时间:2013-04-09 17:47:52

标签: mysql indexing

鉴于以下内容 -

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             |
+-------------------------+---------------------+

2 个答案:

答案 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如何快速决定使用哪个索引,但我认为它与启发式和索引中各行的基数有关,即索引行的“选择性”如何。