我正在尝试找出mysql中索引的设置。mysql什么时候忽略索引?
这是一个实验的结果。我有一个表,在age列上有一个索引,如下所示。
CREATE TABLE `USERS` (
`ID` int(11) NOT NULL,
`FIRSTNAME` varchar(45) NOT NULL,
`LASTNAME` varchar(45) DEFAULT NULL,
`USERNAME` varchar(45) DEFAULT NULL,
`ROLE` int(11) DEFAULT NULL,
`PASSWORD` varchar(45) DEFAULT NULL,
`AGE` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `USERS`
ADD PRIMARY KEY (`ID`),
ADD KEY `AGE` (`AGE`);
解释查询的结果。前三个语句使用索引。第二组语句忽略索引并执行全表扫描。
年龄范围在20到100岁之间。表中有1000行。
/* utilizes the index on AGE */
/* case 1 */
SELECT ID, AGE FROM USERS WHERE AGE > 20;
/* case 2 */
SELECT AGE FROM USERS WHERE AGE > 44;
/* case 3 */
SELECT * FROM USERS WHERE AGE > 84;
/* does not use index on AGE */
/* case 4 */
SELECT AGE, FIRSTNAME FROM USERS WHERE AGE > 83;
/* case 5 */
SELECT * FROM USERS WHERE AGE > 83;
/* case 6 */
SELECT AGE FROM USERS WHERE AGE > 18;
我看到的一些观察。有人能证实我的结论是正确的吗?
1) 选择*将在选择15%或更少的行时使用索引。2) 选择一行或多行时,select age将使用索引。
1条答案
按热度按时间3bygqnnd1#
这15%通常在20%左右,这取决于从表中的数据中收集到的统计数据。我看到有人在他的查询中确定了大约29%作为截止点。你实际上达到了20%:
这就解释了第三、四、五种情况。基本原理是,对于高百分比,表扫描比在索引btree和data+pk btree之间跳转更有效。
该指数是“覆盖”这两个。也就是说,所有必需的列都可以在单个索引中找到。因此,它应该使用索引,而不是进行表扫描:
注:在innodb中,二级索引包括
PRIMARY KEY
含蓄地。也就是说,INDEX(age)
实际上与INDEX(age, id)
.这解释了案例1和案例2,但无法解释案例6。案例6应该使用索引返回整个年龄列表(不是0行,如您的评论所述??)
您的测试只是冰山一角,但是您比大多数初学者更深入地了解mysql相对简单的优化器的深度(我比你领先了好几年。)
这里还有一些经验法则。
请继续试验并公布结果。