复合键中的MySQL列顺序

时间:2014-10-08 10:46:38

标签: mysql key composite

我有疑问,这是我的表:

mysql> show create table watchdog\G
*************************** 1. row ***************************
   Table: watchdog
   Create Table: CREATE TABLE `watchdog` (
       `index1` int(11) NOT NULL DEFAULT '0',
       `index2` int(11) NOT NULL DEFAULT '0',
       `dog` int(11) NOT NULL DEFAULT '9',
        PRIMARY KEY (`index1`,`index2`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8

    1 row in set (0.00 sec)

&LT 1为卤素; 第一个查询:

select index1, index2 
from watchdog 
where index1 > 4000008 and index1 < 4200007; 

结果:

 ...
| 4200001 | 4200002 |
| 4200002 | 4200003 |
| 4200003 | 4200004 |
| 4200004 | 4200005 |
| 4200005 | 4200006 |
| 4200006 | 4200007 |
+---------+---------+

199997 rows in set (0.09 sec)

&LT 2 - ; 第二个问题:

select index1, index2 
from watchdog 
where index2 > 4000009 and index2 < 4200007;

结果:

...
| 4200002 | 4200003 |
| 4200003 | 4200004 |
| 4200004 | 4200005 |
| 4200005 | 4200006 |
+---------+---------+

199997 rows in set (1.68 sec)

他们使用的时间是0.9秒和1.68秒!谁能告诉我为什么?复合键顺序有什么问题?

2 个答案:

答案 0 :(得分:7)

MySQL对复合索引有很好的documentation,您应该查看。让我总结一下您查询的问题。

查询的相关部分是where子句:

where index1 > 4000008 and index1 < 4200007;
index2 > 4000009 and index2 < 4200007;

您按此顺序拥有index1, index2的索引。通常,MySQL可以查看查询并使用索引执行以下三种操作之一:

  1. 决定根本不使用索引(基于统计信息或不适用于查询)
  2. 决定使用index1组件。
  3. 决定使用index1组件 index2
  4. 在第一个查询中,MySQL可以选择第二个选项。因此,它使用index1比较的索引。然后它可能会扫描相应的行,查看索引中的index2值,找到行ID,查找它们并返回行。

    对于第二个where子句,它不能使用索引。索引的第一个键是index1,它在查询中不存在。因此,MySQL必须进行全表扫描。

答案 1 :(得分:0)

因为您定义了一个复合键,只有在where子句中使用了两列或第一列时才能使用该键。

但是你只在慢速查询中使用密钥的第二列。