SQL中索引失效列子及解決方案

一 in 主鍵 和 非主鍵特殊查詢索引是否失效問題

①索引失效

height 爲int(非主鍵)  使用in 會導致索引失效   還有 !=  ,<>,not in 導致索引失效

EXPLAIN SELECT id, name ,age FROM vtiger_knowledgess WHERE height IN('122','11');


EXPLAIN SELECT id, name ,age FROM vtiger_knowledgess WHERE height IN(122,11);


EXPLAIN SELECT id, name ,age FROM vtiger_knowledgess WHERE height NOT IN(122,11);


EXPLAIN SELECT id, name ,age FROM vtiger_knowledgess WHERE height !=122;


EXPLAIN SELECT id, name ,age FROM vtiger_knowledgess WHERE height <>122;

② 與上面作對比索引不失效情況

salesorderworkflowstagesid 爲int(主鍵) 使用in 不會會導致索引失效   還有 !=  ,<>,not in 不會導致索引失效

EXPLAIN SELECT * FROM vtiger_salesorderworkflowstages WHERE salesorderworkflowstagesid IN('9137','9138');


EXPLAIN SELECT * FROM vtiger_salesorderworkflowstages WHERE salesorderworkflowstagesid IN(9137,9138);


EXPLAIN SELECT * FROM vtiger_salesorderworkflowstages WHERE salesorderworkflowstagesid NOT IN(9137,9138);


EXPLAIN SELECT * FROM vtiger_salesorderworkflowstages WHERE salesorderworkflowstagesid !=9137;


EXPLAIN SELECT * FROM vtiger_salesorderworkflowstages WHERE salesorderworkflowstagesid <>9137;

二 varchar 索引失效問題

-- 如果是varchar類型的如果查詢數據類型和數據庫類型不一致會導致索引失效
EXPLAIN SELECT * FROM `vtiger_salesorderworkflowstages` WHERE `auditorid` = 1 LIMIT 0,10;-- 如果 auditorid 是varchar 則錯誤
EXPLAIN SELECT * FROM `vtiger_salesorderworkflowstages` WHERE `auditorid` = '1' LIMIT 0,10;-- 如果 auditorid 是varchar 則正確

三 > 或者 < 號導致索引失效問題

-- 如果是包含> 或者 < 的 想解決 其他索引不失效 就把其他條件放到前面
EXPLAIN SELECT * FROM vtiger_salesorderworkflowstages     WHERE     workflowstagesid > 361031 AND smcreatorid=1  ; -- 會導致smcreatorid 索引失效
EXPLAIN SELECT * FROM vtiger_salesorderworkflowstages     WHERE    smcreatorid=1 AND workflowstagesid < 361031 ;-- 正確
EXPLAIN SELECT * FROM vtiger_salesorderworkflowstages     WHERE    smcreatorid=1 AND (workflowstagesid < 361031 OR workflowstagesid > 361031);-- 正確

四  or 索引失效問題

--  or 會導致複合索引失效 解決方式是 or 前的條件建複合索引 or 後的建複合索引 如果id 一樣就用in(用in會可能會導致索引失效 下面有講到嘿嘿)
 EXPLAIN SELECT * FROM vtiger_salesorderworkflowstages     WHERE    smcreatorid=1 or workflowstagesid = 361031;  --  如果是建的複合索引smcreatorid,workflowstagesid 回導致索引失效 分別建一般索引不會失效

五 in 索引失效問題

-- in 裏包含一個數據能使用到索引
EXPLAIN  SELECT * FROM vtiger_salesorderworkflowstages WHERE  workflowstagesid IN (361031) ; -- 正確
-- in 裏包含兩個以上會導致索引失效
EXPLAIN  SELECT * FROM vtiger_salesorderworkflowstages WHERE  workflowstagesid IN (361031,361035); -- 索引失效
-- 強制索引(in) 如果單獨強制使用索引會導致其他索引失效
SELECT * FROM vtiger_salesorderworkflowstages  FORCE INDEX(workflowstagesid) WHERE  workflowstagesid IN (361031,361035) AND smcreatorid=1; -- 強制索引workflowstagesid生效 導致smcreatorid 索引失效
-- 強制索引(in) 和 其 and 條件可以建立複合索引  可以解決強制索引導致其他and 索引失效的問題
SELECT * FROM vtiger_salesorderworkflowstages  FORCE INDEX(common) WHERE  (workflowstagesid IN (361031,361035) AND smcreatorid=1); -- 建立複合索引 強制使用索引生效 正確

六  in 和 or  一起使用  索引失效問題解決方案

 -- 有強制索引的複合索引(in) 有or 的情況下索引優化使用 使用union可以解決強制索引 和  or 同時使用導致索引失敗的問題
EXPLAIN  SELECT * FROM vtiger_salesorderworkflowstages  FORCE INDEX(common) WHERE  (workflowstagesid IN (361031,361035) AND smcreatorid=1) -- 強制使用索引的複合索引 正確
 UNION
SELECT * FROM vtiger_salesorderworkflowstages  WHERE  sequence=3 ; -- 把 或獨立處理union正確

七  like %***% 索引失效解決辦法 使用索引覆蓋

EXPLAIN SELECT * FROM `vtiger_salesorderworkflowstages`  WHERE `accountname` LIKE '%上海贛帛%';-- 錯誤

EXPLAIN SELECT accountname FROM `vtiger_salesorderworkflowstages`  WHERE `accountname` LIKE '%上海贛帛%'; -- 正確

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章