1. 程式人生 > >[InnoDB]性別欄位為什麼不適合加索引

[InnoDB]性別欄位為什麼不適合加索引

表結構與資料

id為主鍵,id為奇數sex=1,id為偶數sex=0
sex=0,50000條資料;sex=1,50000條資料
表結構在這裡插入圖片描述

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;

新增的索引型別在這裡插入圖片描述

測試結果:

SELECT * FROM people WHERE sex = 0;
SELECT * FROM people WHERE sex = 1;
無sex索引 有sex索引
sex=0 在這裡插入圖片描述 在這裡插入圖片描述
sex=1 在這裡插入圖片描述 在這裡插入圖片描述

可以看到相同的sql,加索引之後比不加索引慢許多。

原因

在InnoDB中每一個表都會有聚集索引,如果表定義了主鍵,則主鍵就是聚集索引。一個表只有一個聚集索引,其餘為普通索引。
索引的結構是B+樹,非葉子節點儲存key,葉子節點儲存value。

  1. 聚集索引,葉子節點儲存行記錄,InnoDB索引和記錄是儲存在一起的。
  2. 普通索引,葉子節點儲存了主鍵的值。

以上表的索引結構示例如下(PS:索引結構僅供參考)
聚集索引
在這裡插入圖片描述
sex列普通索引
在這裡插入圖片描述

在使用普通索引查詢時,會先載入普通索引,通過普通索引查詢到實際行的主鍵。再使用主鍵通過聚集索引查詢相應的行。以此迴圈查詢所有的行。
若直接全量搜尋聚集索引,則不需要在普通索引和聚集索引中來回切換。
相比兩種操作的總開銷可能掃描全表效率更高。

感謝:
https://mp.weixin.qq.com/s/tmkRAmc1M_Y23ynduBeP3Q
https://blog.jcole.us/innodb/
https://blog.csdn.net/u012978884/article/details/52416997?utm_source=blogxgwz0
https://draveness.me/mysql-innodb