【金三銀四】Mysql執行計劃EXPLAIN最佳實踐

【MySql系列】文章導航

【金三銀四】深刻理解MySql索引底層數據結構解密 juejin.im/post/5e0d7b…mysql

【金三銀四】MySql執行計劃EXPLAIN詳解 juejin.im/post/5e12e4…sql

【金三銀四】MySql執行計劃EXPLAIN最佳實踐 juejin.im/post/5e12e4…bash

【金三銀四】MySql索引優化實戰 juejin.im/post/5e12e5…數據結構

最佳實踐

1. 全值匹配

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei';

複製代碼

圖片

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age = 22;

複製代碼

圖片

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age = 22 AND position ='manager';

複製代碼

圖片

2.最左前綴法則

若是索引了多列,要遵照最左前綴法則。指的是查詢從索引的最左前列開始而且不跳過索引中的列。函數

EXPLAIN SELECT * FROM employees WHERE age = 22 AND position ='manager';

複製代碼

圖片

EXPLAIN SELECT * FROM employees WHERE position = 'manager';

複製代碼

圖片

EXPLAIN SELECT * FROM employees WHERE name = 'LiLei';

複製代碼

圖片

3.不要在索引列上作任何操做(計算、函數、(自動or手動)類型轉換),會致使索引失效而轉向全表掃描

EXPLAIN SELECT * FROM employees WHERE name = 'LiLei';

複製代碼

圖片

EXPLAIN SELECT * FROM employees WHERE left(name,3) = 'LiLei';

複製代碼

圖片

4.存儲引擎不能使用索引中範圍條件右邊的列

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age = 22 AND position ='manager';

複製代碼

圖片

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age > 22 AND position ='manager';

複製代碼

圖片

*5.儘可能使用覆蓋索引(只訪問索引的查詢(索引列包含查詢列)),減小select 語句

EXPLAIN SELECT name,age FROM employees WHERE name= 'LiLei' AND age = 23 AND position ='manager';

複製代碼

圖片

EXPLAIN SELECT * FROM employees WHERE name= 'LiLei' AND age = 23 AND position ='manager';

複製代碼

圖片

6.mysql在使用不等於(!=或者<>)的時候沒法使用索引會致使全表掃描

EXPLAIN SELECT * FROM employees WHERE name != 'LiLei';

複製代碼

圖片

7.is null,is not null 也沒法使用索引

EXPLAIN SELECT * FROM employees WHERE name is null;

複製代碼

圖片

8.like以通配符開頭('$abc...')mysql索引失效會變成全表掃描操做

EXPLAIN SELECT * FROM employees WHERE name like '%Lei';

複製代碼

圖片

EXPLAIN SELECT * FROM employees WHERE name like 'Lei%';

複製代碼

圖片

問題:解決like'%字符串%'索引不被使用的方法?post

a)使用覆蓋索引,查詢字段必須是創建覆蓋索引字段mysql索引

EXPLAIN SELECT name,age,position FROM employees WHERE name like '%Lei%';

複製代碼

圖片

b)當覆蓋索引指向的字段是varchar(380)及380以上的字段時,覆蓋索引會失效!優化

9.字符串不加單引號索引失效

EXPLAIN SELECT * FROM employees WHERE name = '1000';

複製代碼

圖片

EXPLAIN SELECT * FROM employees WHERE name = 1000;

複製代碼

圖片

10.少用or,用它鏈接時不少狀況下索引會失效

EXPLAIN SELECT * FROM employees WHERE name = 'LiLei' or name = 'HanMeimei';

複製代碼

圖片

11.in和exsits優化

原則:小表驅動大表,即小的數據集驅動大的數據集ui

  • in:當B表的數據集必須小於A表的數據集時,in優於existsspa

    select * from A where id in (select id from B)

explain select * from film where id in(select film_id from film_actor);

複製代碼

圖片

  • exists:當A表的數據集小於B表的數據集時,exists優於in 將主查詢A的數據,放到子查詢B中作條件驗證,根據驗證結果(true或false)來決定主查詢的數據是否保留 select * from A where exists (select 1 from B where B.id = A.id) #A表與B表的ID字段應創建索引
explain select * from film where exists (select 1 from film_actor where film_actor.film_id = film.id)

複製代碼

圖片

一、EXISTS (subquery)只返回TRUE或FALSE,所以子查詢中的SELECT * 也能夠是SELECT 1或select X,官方說法是實際執行時會忽略SELECT清單,所以沒有區別

二、EXISTS子查詢的實際執行過程可能通過了優化而不是咱們理解上的逐條對比

三、EXISTS子查詢每每也能夠用JOIN來代替,何種最優須要具體問題具體分析

總結

圖片

like KK%至關於=常量,%KK和%KK% 至關於範圍

相關文章
相關標籤/搜索