[InnoDB]性别字段为何不适合加索引

表结构与数据

id为主键,id为奇数sex=1,id为偶数sex=0 sex=0,50000条数据;sex=1,50000条数据 mysql

CREATE TABLE `people` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `sex` tinyint(1) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8;
复制代码
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_initData`()
BEGIN
    DECLARE i INT DEFAULT 1;
    WHILE i<=100000 DO
        INSERT INTO people(name, sex) VALUES(CONCAT('姓名',i),0);
        SET i = i+1;
    END WHILE;
END

CALL proc_initData();
UPDATE people SET sex = 1 WHERE MOD(id,2) = 1;
复制代码

添加的索引类型 sql

测试结果:

SELECT * FROM people WHERE sex = 0;
SELECT * FROM people WHERE sex = 1;
复制代码
无sex索引 有sex索引
sex=0
在这里插入图片描述
在这里插入图片描述
sex=1
在这里插入图片描述
在这里插入图片描述

添加索引后的EXPLAIN: 测试

能够看到相同的sql,加索引以后比不加索引慢许多。

缘由

在InnoDB中每个表都会有汇集索引,若是表定义了主键,则主键就是汇集索引。一个表只有一个汇集索引,其他为普通索引。 索引的结构是B+树,非叶子节点存储key,叶子节点存储value。ui

  1. 汇集索引,叶子节点存储行记录,InnoDB索引和记录是存储在一块儿的。
  2. 普通索引,叶子节点存储了主键的值。

以上表的索引结构示例以下(PS:索引结构仅供参考) 汇集索引spa

sex列普通索引

在使用普通索引查询时,会先加载普通索引,经过普通索引查询到实际行的主键。再使用主键经过汇集索引查询相应的行。以此循环查询全部的行。 若直接全量搜索汇集索引,则不须要在普通索引和汇集索引中来回切换。 相比两种操做的总开销可能扫描全表效率更高。

参考:
mp.weixin.qq.com/s/tmkRAmc1M…
blog.jcole.us/innodb/
blog.csdn.net/u012978884/…
draveness.me/mysql-innod….net

相关文章
相关标签/搜索