MySQL索引,当可能有多个索引时
鉴于以下情况-MySQL索引,当可能有多个索引时,mysql,indexing,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) ); ex
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\u col1而不是idx\u col1\u col2
+----+-------------+------------------+------+------------------------+----------+---------+-------+------+-------------+
| 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 |
+-------------------------+---------------------+
我无法在这里解释您的情况,但有时MySQL只是选择了错误的索引。也许数据库足够小,它知道在这种情况下它没有任何区别 这个查询非常简单,它应该知道哪个索引是最合适的
我可以根据经验说,当查询变得越来越复杂,尤其是当表变得非常大时,MySQL有时是随机的?决定选择另一个索引并使用它,然后查询可以从0.01秒变为100秒以上,因此如果您知道哪个索引是正确的,请使用FORCE index。即使您使用索引,MySQL有时也会选择另一个具有不同结果的索引以提高查询速度。我同意Floaf的说法,MySQL有时会选择错误的索引,但我认为这里的情况并非如此。MySQL将行数和数据结构纳入其选择索引的决策中 对于这样一个相当简单的查询,如果表中包含的行少于100行或者甚至是空的,MySQL可能根本不使用任何索引。仅仅扫描所有表行似乎比使用索引在计算上更便宜。在解释计划中,您可以看到键列显示为idx_col1,但额外的列没有显示使用索引 如果表包含大约100行以上,MySQL将开始使用idx_col1。解释计划将向您展示这一点。只有当col1中实际包含字符串“FOO”的行数超过100行时,MySQL才会注意到使用idx_col1并不能充分减少暂定结果集,因为它必须扫描col2中剩余的100行以查找值“BAR”。因此,它将切换到idx_col1_col2
我不完全确定MySQL如何快速决定使用哪个索引,但我认为这与启发式和索引中各行的基数有关,即索引行的选择性有多高。谢谢。我认为使用索引意味着它正在从索引中检索select值?尝试两种变体,注释掉idx_col1。另外,将col1、col2切换到*。你能分享你从哪里得到的100行信息吗?MySQL文档说,如果额外的列使用where和using索引,这意味着该索引用于执行键值的查找。对于100行或更多行数据,我将id设置为自动递增主键。然后我添加了3行随机值。为了乘法,我做了一些类似插入学习索引col1、col2、col3的操作,从学习索引中选择CONCATcol2、'q',CONCATcol1、'z',CONCATcol3、'c';反复地这将使每次执行的行数加倍,并以某种方式洗牌和修改新插入的行值。