为什么 MySQL 在选择查询中不使用最左边的索引字段(UK - col1、col2、col3)?

The*_*der 1 mysql index unique-constraint

我有一个具有以下结构的部门表

创建表

CREATE TABLE `department` (
  `id` binary(16) NOT NULL,
  `name` varchar(255) NOT NULL,
  `type` int(11) NOT NULL,
  `status` tinyint(4) NOT NULL,  -- Possible values are 0,1,2 only
  PRIMARY KEY (`id`),
  UNIQUE KEY `UK_2xsp2nild3xbgkg4pln7cviib` (`status`,`type`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)

以下查询不使用status索引,因为它是唯一约束中最左边的列。

EXPLAIN SELECT * FROM department d WHERE d.status = 1;

    id  select_type  table   partitions  type    possible_keys                 key     key_len  ref       rows  filtered  Extra        
------  -----------  ------  ----------  ------  ----------------------------  ------  -------  ------  ------  --------  -------------
     1  SIMPLE       d       (NULL)      ALL     UK_2xsp2nild3xbgkg4pln7cviib  (NULL)  (NULL)   (NULL)       4    100.00  Using where  
Run Code Online (Sandbox Code Playgroud)

但是当查询另一个对单个列具有唯一约束的表时,它使用索引。

CREATE TABLE `account_unit` (
  `id` binary(16) NOT NULL,
  `status` tinyint(4) NOT NULL,
  `unit_name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UK_2x8b55sxftahu8cjbqld9sw9b` (`unit_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

EXPLAIN SELECT * FROM account_unit au WHERE au.`unit_name` = 'AU1'

    id  select_type  table   partitions  type    possible_keys                 key                           key_len  ref       rows  filtered  Extra   
------  -----------  ------  ----------  ------  ----------------------------  ----------------------------  -------  ------  ------  --------  --------
     1  SIMPLE       au      (NULL)      const   UK_2x8b55sxftahu8cjbqld9sw9b  UK_2x8b55sxftahu8cjbqld9sw9b  767      const        1    100.00  (NULL)  
Run Code Online (Sandbox Code Playgroud)

根据我的理解,多列约束上的最左侧列将用作选择查询的索引。如果我错了,请启发我。

G-N*_*get 5

这几乎可以肯定是由于第一列索引的基数较低。由于只有 3 个值,优化器决定最好对表进行全面扫描。

使用第一列上的索引将指向大约三分之一的行。根据主键查找许多行可能会导致几乎所有主键页面以及大部分二级索引页面都被拉入缓冲区,从而导致更多的内存使用和潜在的磁盘流量。总体而言,如果可能基于二级索引查找选择大部分数据,则仅对数据进行完整扫描会更有效并且通常速度大致相同。