MySQL索引失效場景 |Java 刷題打卡

本文正在參加「Java主題月 - Java 刷題打卡」,詳情查看 活動連接sql

題目:MySQL索引失效場景

知識點:

針對索引失效場景,便於優化SQL查詢markdown

基於如下表結構驗證索引失效場景app

CREATE TABLE `dynamic_info` (
  `id` int(32) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL COMMENT '工做動態標題',
  `content` text COMMENT '工做動態內容',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
  `creator` varchar(64) DEFAULT NULL COMMENT '建立人',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
  `docid` text COMMENT '愛數文件id',
  `version_num` int(11) DEFAULT NULL COMMENT '版本號',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='工做動態';
複製代碼

添加組合索引、全文索引函數

alter table dynamic_info 
    add index 
    idx_dynamic_titleCreatorVersionNum(title,creator,version_num);
   
 alter table dynamic_info 
    add FULLTEXT 
 idx_dynamic_content(content);
複製代碼

列出索引生效相關場景

  1. 使用全值匹配,查詢條件全使用索引查詢,索引有效
EXPLAIN select * from dynamic_info where title = '通知' and creator = '5' and version_num = 1;
複製代碼

1png.png 從執行計劃可知索引總長度爲1287post

  1. 查詢符合最佳左前綴法則,查詢條件僅使用組合索引第一個字段,索引有效
EXPLAIN select * from dynamic_info where title = '通知';
複製代碼

2.png

  1. 使用組合索引第一二個字段做爲查詢條件,索引有效
EXPLAIN select * from dynamic_info where title = '通知' and creator = '5';
複製代碼

3.png 4.使用組合索引第一三個字段做爲查詢條件,索引有效性能

EXPLAIN select * from dynamic_info where title = '通知' and version_num = 2;
複製代碼

4.png

總結:第一、二、三、4種狀況因查詢條件命中組合索引狀況不一樣,而使用的索引長度

索引失效相關場景以下:

1.使用組合索引第二三個字段做爲查詢條件,索引失效優化

EXPLAIN select * from dynamic_info where creator = '5' and version_num = 1;
複製代碼

5.png

  1. 在索引字段上進行計算、函數、類型轉換,索引失敗
EXPLAIN select * from dynamic_info where LEFT(title,1) = '通';
複製代碼

6.png 使用left(str,length)函數函數對字符串截取,致使索引失效ui

  1. 存儲引擎不能使用索引中範圍條件右邊的列,索引部分失效
EXPLAIN select * from dynamic_info where title = '通知' and creator = '5';

EXPLAIN select * from dynamic_info where title = '通知' and creator > '5' and version_num = 2;
複製代碼

7.png

結合以前的key_len分析,索引用到一個、二個、三個字段時,key_len分別對應102三、128二、1287,此處的查詢只用到title和creator字段,因爲creator是個範圍查詢,致使索引version_num字段上索引失效url

  1. 儘可能使用覆蓋索引,select索引字段查詢,減小使用select *
EXPLAIN select title,creator,version_num from dynamic_info where title = '通知' and version_num = 1 and creator = '5';

EXPLAIN select * from dynamic_info where title = '通知' and creator = '5' and  version_num = 1 ;
複製代碼

8.png

select title,creator,version_num 用到覆蓋索引,索引類型爲ref,性能好於range,此外Extra顯示用到Using index,表名只須要從索引樹中尋找數據,不需在表中查找,而select * 可能須要查詢非索引其餘字段,Extra顯示用到Using where,代表須要到表中查找。因此select * 比select 索引字段 性能要低spa

  1. 索引字段爲varchar類型,查詢條件沒添加引號,索引失效
EXPLAIN select * from dynamic_info where title = 20210520;
複製代碼

9.png MySQL執行一條SQL語句先會優化SQL,將數字轉換成String來查詢,致使索引失效 解決索引失效方法:字段類型爲varchar,查詢的值爲數字,須要添加單引號,索引纔有效

  1. 查詢條件使用不等於(!= 或<>),索引失效
EXPLAIN select * from dynamic_info where title != '通知';
EXPLAIN select * from dynamic_info where title <> '通知';
複製代碼

10.png 7. 查詢條件使用is null,is not null,索引失效

EXPLAIN select * from dynamic_info where content is null;
EXPLAIN select * from dynamic_info where content is not null;
複製代碼

11.png 8. 使用like以通配符開頭(%?%),索引失效

EXPLAIN select * from dynamic_info where content like '%通知';
EXPLAIN select * from dynamic_info where content like '%通知%';
EXPLAIN select * from dynamic_info where content like '通知%';
複製代碼

12.png 針對已有組合索引,查詢使用like以通配符開頭的SQL,可以使用覆蓋索引,即select的字段所有都被創建了索引

EXPLAIN select title,creator,version_num from dynamic_info where title like '%通知%';
複製代碼

12.2.png 9. 使用or鏈接條件,索引失效

EXPLAIN select content from dynamic_info where content = '通知' or content = '5';
複製代碼

13.png

相關文章
相關標籤/搜索