本片博文承接上一篇 《乾貨!SQL性能優化,書寫高質量SQL語句》。這裏很是感謝你們,很給面子,評論區給了不少意見和指導!上篇文章出現太多的理論知識,並無用具體的測試用例說服你們,那麼本片乾貨分享主要針對上篇掘友們提出的疑問點進行回答,提供詳細的測試用例。若有不足還請賜教~mysql
數據庫版本 mysql 5.7.26sql
首先先建立一張測試表數據庫
CREATE TABLE `student` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`name` varchar(255) NOT NULL,
`class` varchar(255) DEFAULT NULL,
`page` bigint(20) DEFAULT NULL,
`status` tinyint(3) unsigned NOT NULL COMMENT '狀態:0 正常,1 凍結,2 刪除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4
複製代碼
批量新增100w條數據性能優化
DELIMITER ;;
CREATE PROCEDURE insertData()
BEGIN
declare i int;
set i = 1 ;
WHILE (i < 1000000) DO
INSERT INTO student(`name`,class,`page`,`status`)
VALUES(CONCAT('class_', i),
CONCAT('class_', i),
i, (SELECT FLOOR(RAND() * 2)));
set i = i + 1;
END WHILE;
commit;
END;;
CALL insertData();
複製代碼
name 字段 不加 索引,進行測試, 耗時 0.8sbash
SELECT * FROM student WHERE `name` IN
('class_1','class_100','class_1000','class_100000');
複製代碼
name 字段加索引後,測試耗時 0.021spost
那麼咱們發現where 語句使用 IN 是走索引的性能
再查一下 student 表中的 status 字段 in 的狀況測試
SELECT * FROM student WHERE `status` IN(0,2);
複製代碼
加索引後,由於數據量大,並未走索引,如圖所示:優化
總結ui
翻閱大量資料進行測試,若是是mysql5.5以前的版本,確實是不會走索引的,在5.5及以後的版本中,MySql作了優化,在2010年發佈的5.5版本中,優化器對 IN 操做符能夠自動完成優化,針對創建了索引的列可使用索引,沒有索引的列仍是會走全表掃描,可是若是數據量大,例如估計爲全表80%,會走全表掃描!
咱們分三種狀況來測試
SELECT * FROM student WHERE `name` is not null
複製代碼
SELECT * FROM student WHERE `name` is null
複製代碼
分析: IS NULL 使用了索引 , IS NOT NULL 沒有走索引
分析: IS NULL 使用了索引 , IS NOT NULL 沒有走索引
分析: IS NULL 沒有走索引 , IS NOT NULL 也沒有走索引
結論
is not null無論字段是否爲空都不會走索引,is null在字段容許爲空時會使用索引!