1. 程式人生 > >MySQL:explain(執行計劃)詳解

MySQL:explain(執行計劃)詳解

  1. 本文主要介紹了MySQL效能分析以及explain的使用,
  2. 包括:組合索引、慢查詢分析、MYISAMINNODB的鎖定、MYSQL的事務配置項等

        索引類似大學圖書館建書目索引,可以提高資料檢索的效率,降低資料庫的IO成本。MySQL在300萬條記錄左右效能開始逐漸下降,雖然官方文件說500~800w記錄,所以大資料量建立索引是非常有必要的。MySQL提供了Explain,用於顯示SQL執行的詳細資訊,可以進行索引的優化。

導致SQL執行慢的原因:

      1.硬體問題。如網路速度慢,記憶體不足,I/O吞吐量小,磁碟空間滿了等。

      2.沒有索引或者索引失效。(一般在網際網路公司,DBA會在半夜把表鎖了,重新建立一遍索引,因為當你刪除某個資料的時候,索引的樹結構就不完整了。所以網際網路公司的資料做的是假刪除.一是為了做資料分析,二是為了不破壞索引 )

      3.資料過多(分庫分表)

      4.伺服器調優及各個引數設定(調整my.cnf)

分析原因時,一定要找切入點:

      1.先觀察,開啟慢查詢日誌,設定相應的閾值(比如超過3秒就是慢SQL),在生產環境跑上個一天過後,看看哪些SQL比較慢。

      2.Explain和慢SQL分析。比如SQL語句寫的爛,索引沒有或失效,關聯查詢太多(有時候是設計缺陷或者不得以的需求)等等。

      3.Show Profile是比Explain更近一步的執行細節,可以查詢到執行每一個SQL都幹了什麼事,這些事分別花了多少秒。

      4.找DBA或者運維對MySQL進行伺服器的引數調優。

1.使用explain語句去檢視分析結果 

  1. explain select * from test1 where id=1;
  2. 會出現:id selecttype table type possible_keys key key_len ref rows extra各列。


  1. 其中,
  2. type=const 表示通過索引一次就找到了;
  3. key=primary的話,表示使用了主鍵;
  4. type=all, 表示為全表掃描;
  5. key=null 表示沒用到索引。
  6. type=ref 因為這時認為是多個匹配行,在聯合查詢中,一般為REF

2.MYSQL中的組合索引 

  • 假設表有id,key1,key2,key3,把三者形成一個組合索引,則如: 
  1. where key1=....
  2. where key1=1 and key2=2
  3. where key1=3 and key2=3 and key3=2
  • 根據最左字首原則,這些都是可以使用索引的,如from test where key1=1 order by key3。
  • 用explain分析的話,只用到了normal_key索引,但只對where子句起作用,而後面的order by需要排序。

3.使用慢查詢分析(實用)

  1. my.ini中:
  2. long_query_time=1
  3. log-slow-queries=d:\mysql5\logs\mysqlslow.log
  • 把超過1秒的記錄在慢查詢日誌中 
  • 可以用mysqlsla來分析之。
  • 也可以在mysqlreport中,有如 DMS分別分析了select ,update,insert,delete,replace等所佔的百分比

4.MYISAM和INNODB的鎖定 

  1. myisam中,用的是表鎖,比如在多個UPDATE操作後,再SELECT時,
  2. 會發現SELECT操作被鎖定了,必須等所有UPDATE操作完畢後,才能SELECT
  3. innodb的話則不同了,用的是行鎖,不存在上面問題。
  1. MyISAMInnoDB講解
    1. InnoDBMyISAM是許多人在使用MySQL時最常用的兩個表型別,這兩個表型別各有優劣,視具體應用而定。
    2. 基本的差別為:
    3. MyISAM型別不支援事務處理等高階處理,而InnoDB型別支援。
    4. MyISAM型別的表強調的是效能,其執行數度比InnoDB型別更快,但是不提供事務支援,
    5. InnoDB提供事務支援以及外部鍵等高階資料庫功能
  2. 以下是一些細節和具體實現的差別:
  3. 1.InnoDB不支援FULLTEXT型別的索引。
  4. 2.InnoDB中不儲存表的具體行數,也就是說,執行select count(*) from table時,
  5. InnoDB要掃描一遍整個表來計算有多少行,但是MyISAM只要簡單的讀出儲存好的行數即可。
  6. 注意的是,當count(*)語句包含 where條件時,兩種表的操作是一樣的。
  7. 3.對於AUTO_INCREMENT型別的欄位,InnoDB中必須包含只有該欄位的索引,
  8. 但是在MyISAM表中,可以和其他欄位一起建立聯合索引。
  9. 4.DELETE FROM table時,InnoDB不會重新建立表,而是一行一行的刪除。
  10. 5.LOAD TABLE FROM MASTER操作對InnoDB是不起作用的
  11. 解決方法是首先把InnoDB表改成MyISAM表,匯入資料後再改成InnoDB表,
  12. 但是對於使用的額外的InnoDB特性(例如外來鍵)的表不適用。
    1. 另外,InnoDB表的行鎖也不是絕對的,假如在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表,
    2. 例如update table set num=1 where name like “%aaa%”
    3. 兩種型別最主要的差別就是Innodb支援事務處理與外來鍵和行級鎖
    4. MyISAM不支援.所以MyISAM往往就容易被人認為只適合在小專案中使用。
    5. 作為使用MySQL的使用者角度出發,InnodbMyISAM都是比較喜歡的,
    6. 如果資料庫平臺要達到需求:99.9%的穩定性,方便的擴充套件性和高可用性來說的話,MyISAM絕對是首選。
  13. 原因如下:
  14. 1、平臺上承載的大部分專案是讀多寫少的專案,而MyISAM的讀效能是比Innodb強不少的。
  15. 2MyISAM的索引和資料是分開的,並且索引是有壓縮的,記憶體使用率就對應提高了不少。
  16. 能載入更多索引,而Innodb是索引和資料是緊密捆綁的,
  17. 沒有使用壓縮從而會造成InnodbMyISAM體積龐大不小。
  18. 3、經常隔12個月就會發生應用開發人員不小心update一個表where寫的範圍不對,導致這個表沒法正常用了,
  19. 這個時候MyISAM的優越性就體現出來了,隨便從當天拷貝的壓縮包取出對應表的檔案,
  20. 隨便放到一個數據庫目錄下,
  21. 然後dumpsql再導回到主庫,並把對應的binlog補上
  22. 如果是Innodb,恐怕不可能有這麼快速度,別和我說讓Innodb定期用匯出xxx.sql機制備份,
  23. 因為最小的一個數據庫例項的資料量基本都是幾十G大小。
  24. 4、從接觸的應用邏輯來說,select count(*)order by 是最頻繁的,大概能佔了整個sql總語句的60%以上的操作,
  25. 而這種操作Innodb其實也是會鎖表的,很多人以為Innodb是行級鎖,那個只是where對它主鍵是有效,非主鍵的都會鎖全表的。
  26. 5、還有就是經常有很多應用部門需要我給他們定期某些表的資料MyISAM的話很方便,只要發給他們對應那表的frm.MYD,MYI的檔案讓他們自己在對應版本的資料庫啟動就行,
  27. Innodb就需要匯出xxx.sql了,因為光給別人檔案,受字典資料檔案的影響,對方是無法使用的。
  28. 6、如果和MyISAMinsert寫操作的話,Innodb還達不到MyISAM的寫效能,如果是針對基於索引的update操作,
  29. 雖然MyISAM可能會遜色Innodb,但是那麼高併發的寫,從庫能否追的上也是一個問題,還不如通過多例項分庫分表架構來解決。
  30. 7、如果是用MyISAM的話,merge引擎可以大大加快應用部門的開發速度,
  31. 他們只要對這個merge表做一些select count(*)操作,非常適合大專案總量約幾億的rows某一型別(如日誌,調查統計)的業務表。
  32. 當然Innodb也不是絕對不用,用事務的專案就用Innodb的。
  33. 另外,可能有人會說你MyISAM無法抗太多寫操作,但是可以通過架構來彌補。

5.MYSQL的事務配置項 

  1. innodb_flush_log_at_trx_commit=1
  2. 表示事務提交時立即把事務日誌flush寫入磁碟,同時資料和索引也更新,很費效能。
  3. innodb_flush_log_at_trx_commit=0
  4. 事務提交時,不立即把事務日誌寫入磁碟,每隔1秒寫一次,MySQL掛了可能會丟失事務的資料。
  5. innodb_flush_log_at_trx_commit=2,在整個作業系統掛了時才可能丟資料,一般不會丟失超過1-2秒的更新。
  6. 事務提交時,立即寫入磁碟檔案(這裡只是寫入到系統核心緩衝區,但不立即重新整理到磁碟,而是每隔1秒重新整理到磁碟,同時更新資料和索引),
  7. 這種方案是不是價效比好一些,當然如何配置,決定於你對系統資料安全性的要求。

explain用法詳解

  1. EXPLAIN tbl_name或:EXPLAIN [EXTENDED] SELECT select_options
  2. 前者可以得出一個表的欄位結構等等,後者主要是給出相關的一些索引資訊,而今天要講述的重點是後者。

  • 舉例
  • 各個屬性的含義
  • id :select查詢的序列號
--id相同,執行順序由上而下 
--id不同,值越大越先被執行
    • select_type:select查詢的型別,主要是區別普通查詢和聯合查詢、子查詢之類的複雜查詢。
      1. a.SIMPLE:查詢中不包含子查詢或者UNION
      2. b