2014-10-08 40 views
3

我有一个疑问,这是我的表:MySQL的列顺序在复合键

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) 

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

< 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.9sec和1.68sec!有谁能告诉我为什么?复合钥匙订单有什么问题?

回答

7

对于复合索引,MySQL有很好的documentation,您应该查看。让我为你查询总结这个问题。

查询的相关部分是where条款:

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

index1, index2有一个指标,按照这个顺序。在一般情况下,MySQL能够看一个查询,做的三件事情的指数之一:

  1. 决定不使用在所有的索引(基于统计或不适用的查询)
  2. 决定使用index1零件。
  3. 决定使用index1组件index2

在第一个查询中,MySQL可以选择第二个选项。因此,它使用index1比较的索引。然后它可能会扫描相应的行,查看索引中的值index2,查找行ID,查找它们并返回行。

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

0

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

但是,您只能在缓慢查询中使用密钥的第二列。