1. 程式人生 > >MySql優化-索引命中

MySql優化-索引命中

在專案開發中SQL是必不可少的,表索也一樣.這些SQL的執行效能不知道嗎?有多少是命中了索引的?命中哪個索引?索引中有哪個是無效索引?這些無效索引是否會影響系統的效能?帶著這些問題我們一起來學習一下.
  MySql中是通過 Explain 命令來分析低效SQL的執行計劃。命令的使用很簡單.
示例 explain select * from adminlog
執行結果:
id  select_type table   partitjons  type    possible_keys   key key_len ref row filtered    Extra
1   SIMPLE  adminlog        ALL                 2
100 執行結果每一列的說明: 1、 select_type : 查詢型別,常見的值[SIMPLE:簡單表,不使用表連線或子查詢。PRIMARY : 主查詢,外層的查詢。UNION 第二個或者後面的查詢語句。SUBQUERY : 子查詢中的第一個select] 2、table :輸出結果的表 3type : 表示MySql在表中找到所需行的方式,或者叫訪問型別。常見的型別: ALL index range ref eq_ref const,system NULL 從左到右,效能由最差到最好。   3.1 type=ALL 全表掃描,   3.2 typeindex 索引全掃描,遍歷整個索引來查詢匹配的行   3.3
type=range 索引範圍掃描,常見於 <,<=,>,>=,between,in等操作符。   例     explain select * from adminlog where id>0 ,     explain select * from adminlog where id>0 and id<=100     explain select * from adminlog where id in (1,2)   3.4 type=ref 使用非唯一索引或唯一索引的字首掃描,返回匹配某個單獨值的記錄行。ref還經常出現在JOIN操作中   3.5
type=eq_ref 類似於ref,區別就在使用的索引是唯一索引,對於每個索引鍵值,表中有一條記錄匹配;簡單來說,說是多表連線中使用 主建或唯一健作為關聯條件   3.6 type=const/system 單表中最多有一個匹配行。主要用於比較primary key [主鍵索引]或者unique[唯一]索引,因為資料都是唯一的,所以效能最優。條件使用=。   3.7 type=NULL 不用訪問表或者索引,直接就能夠得到結果  例 explain select 1 from dual,型別type 還有其他值 如ref_or_null : 與ref 類似,區別在於條件中包含對NULL的查詢. index_merge : 索引合併優化, unique_subquery : in的後面是一個主鍵欄位的子查詢。index_subquery : 與 unique_subquery 類似,區別在於in的後面是查詢非唯一索引欄位的子查詢 4、possible_keys : 可能使用的索引列表. 5、key : 實現執行使用索引列表 6、key_len : 索引的長度 7、ref : 顯示使用哪個列或常數與key一起從表中選擇行。 8、row : 執行查詢的行數,簡單且重要,數值越大越不好,說明沒有用好索引 9、filtered: 10、Extra: 該列包含MySQL解決查詢的詳細資訊。   10.1 Not exists   10.2 range checked for each record     沒有找到合適的索引   10.5 using index 只使用索引樹中的資訊而不需要進一步搜尋讀取實際的行來檢索表中的資訊。就是建議取索引列。這樣就可以不要通過索引去實際表中找資料了。直接返回索引列的資料。一次查詢。否則就是索引表查一次,實際表中查一次。   10.6 using temporary 為了解決查詢,MySQL需要建立一個臨時表來容納結果。典型情況如查詢包含可以按不同情況列出列的GROUP BYORDER BY子句時。 無效索引: 資料變化不大的列。如XX型別,是否有效,專案ID等列的索引都是無效的。這些無效索引還是影響Insert 、Update、Delete 語句的效能。因為這些語包的執行都要對索引表進行更新。又因為這些表的值變化不大,資料庫很難為他們合理分配索引。所以影響語句的效能。 IN,OR 是否會走索引: 一條SQL會不會走索引一個看條件使用的運算子,另一個看有沒有索引。所以SQL會不會走索引和IN.OR,group by 沒有關係。 什麼運算子不走索引,<>,!= OR 有個點要注意一下:就OR前後兩個條件都要有索引整個SQL才會使用索引。只要有一個條件沒索引那麼整個SQL都不使用索引。 如果出現OR的一個條件沒有索引時,建議使用 union 例: explain SELECT * FROM cbdfinance.adminlog where id = 1 union SELECT * FROM cbdfinance.adminlog where OriginalData='UpdateModelErrorMsg'; 結果: 1 PRIMARY adminlog const PRIMARY PRIMARY 4 const 1 100.00 2 UNION adminlog ALL 11 10.00 Using where UNION RESULT <union1,2> ALL Using temporary 使用OR第二個條件沒有索引: explain SELECT * FROM cbdfinance.adminlog where id = 1 or OriginalData='UpdateModelErrorMsg'; 結果: 1 SIMPLE adminlog ALL PRIMARY 11 18.18 Using where explain SELECT * FROM cbdfinance.adminlog where id = 1 or id=2; explain SELECT * FROM cbdfinance.adminlog where id = 1 or SearchText1='UpdateModelErrorMsg'; explain SELECT * FROM cbdfinance.adminlog where id in (1,2) explain SELECT * FROM cbdfinance.adminlog group by SearchText1