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)
根据我的理解,多列约束上的最左侧列将用作选择查询的索引。如果我错了,请启发我。
这几乎可以肯定是由于第一列索引的基数较低。由于只有 3 个值,优化器决定最好对表进行全面扫描。
使用第一列上的索引将指向大约三分之一的行。根据主键查找许多行可能会导致几乎所有主键页面以及大部分二级索引页面都被拉入缓冲区,从而导致更多的内存使用和潜在的磁盘流量。总体而言,如果可能基于二级索引查找选择大部分数据,则仅对数据进行完整扫描会更有效并且通常速度大致相同。