Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL索引,当可能有多个索引时_Mysql_Indexing - Fatal编程技术网

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';反复地这将使每次执行的行数加倍,并以某种方式洗牌和修改新插入的行值。