复合键中的 MySQL 列顺序

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

<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> Second query:

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秒!谁能告诉我为什么?复合键顺序有什么问题?

最佳答案

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 必须进行全表扫描。

关于复合键中的 MySQL 列顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26255039/

相关文章:

使用设置目录时 MySQL 导出 INTO OUTFILE --secure-file-priv 错误

mysql - 有没有人有相同的名字、中间名和姓氏?列出他们和他们的完整地址

mysql - 在 Docker 中配置 mysql

swift - 显示 Parse 数据库 Swift 中单元格的两个键

design-patterns - 设计模式:合成与合成

box2d - 组成和射弹

design-patterns - 组件和复合之间具有双向关联的复合模式

php - 在多列上使用子句从 1/n 表中过滤字段

python - 如何使用Python中的字典替换列表中的字符

node.js - MongoDB 将变量名称更新为键 (Node.JS)