MySQL中主键和多列索引的优先级?

时间:2018-06-27 02:09:11

标签: mysql sql

CREATE TABLE student (                                  
  id int(11) NOT NULL AUTO_INCREMENT,                   
  name varchar(128) DEFAULT NULL,                 
  age int(11) NOT NULL,
  update_time timestamp NULL DEFAULT CURRENT_TIMESTAMP 
    ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id),                                   
       KEY idx_name_age (name,age),                         
       KEY idx_name_age_update_time (name,age,update_time) 
     ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

然后我使用EXPLAIN来获取有关MySQL中索引如何工作的一些信息,当执行这样的sql时,我发现一件事让我感到困惑:

EXPLAIN 
  SELECT * FROM springboot.student
    WHERE id>1 AND id <5 AND NAME = 'tank' AND age =23 ;

结果:

id   select_type   table     type     possible_keys    key            key_len   ref             rows  Extra        
------  -----------  -------  ------  ---------------------------------------------  ------------  -------  -----------  ------  -------------
1  SIMPLE       student  ref     PRIMARY,idx_name_age,idx_name_age_update_time  idx_name_age  391      const,const       1  Using where 

我想知道为什么要把它交给我。

1 个答案:

答案 0 :(得分:0)

没有固有的优先级。您影响了SQL优化器,但无法控制它。那实际上很好。基于规则的优化器已经过时了很长一段时间,而基于成本的优化器风靡一时。

发生了什么事?[基于成本的] SQL优化器生成了一个取决于许多参数的执行计划。例如:

  • 表的大小。
  • 存在索引。
  • 每列的值分布。
  • 过滤条件的选择性。
  • 表格统计信息的最新程度。

似乎您希望使用主键通过索引读取表。您需要将其翻译为优化程序条款:

  • 访问权限:通过主键索引,使用索引范围扫描
  • 过滤:通过NAME = 'tank' AND age = 23

然而,优化器决定在某些方面有所不同:

  • 访问权限:使用索引搜索按索引(name, age)
  • 过滤:按主键索引。

通常,“索引搜索”比“索引范围扫描”快得多。也许这就是为什么优化器选择第二个。

您实际上测量了执行时间吗?记住计划不是查询。测量,测量,测量。