查看查詢優化器如何決定查詢的主要方法。即查看sql的執行效率,幫助咱們分析select語句,讓咱們知道查詢效率低下的緣由,從而改進咱們的查詢。用法就是sql語句前加explain。mysql
Explain具備侷限性,它不會考慮觸發器、存儲過程或函數、緩存對查詢結果的影響,不會考慮mysql執行查詢所作的特定優化,基於統計信息的估算,並不是精確值。sql
分析SQL執行帶來的開銷是優化SQL的重要手段。在MySQL數據庫中,能夠經過配置profiling參數來啓用SQL剖析。該參數開啓後,後續執行的SQL語句都將記錄其資源開銷,諸如IO,上下文切換,CPU,Memory等等。數據庫
開啓profile:set @@profiling = 1; #開啓後僅對當前sesion有效緩存
查看profile是否開啓:select @@profiling; #1爲開啓,0位關閉併發
查看當前已經被記錄的sql:show profiles;函數
查看profile結果:show profile for query n; #n爲show profile 中的query_id高併發
show profile能夠看到sql執行計劃中每步的執行時間,以及cpu、內存、io的消耗:show profile cpu for query 1;#查看cpu消耗工具
show profile block io for query 1;#查看io消耗性能
show profile memory for query 1;#查看cpu優化
也能夠一塊兒寫:show profile cpu ,block io for query 1;
1)減小IO次數:
IO永遠是數據庫最容易瓶頸的地方,這是由數據庫的職責所決定的,大部分數據庫操做中超過90%的時間都是 IO 操做所佔用的,減小 IO 次數是 SQL 優化中須要第一優先考慮,固然,也是收效最明顯的優化手段。
2)下降CPU計算:
除了 IO 瓶頸以外,SQL優化中須要考慮的就是 CPU 運算量的優化了。order by, group by,distinct … 都是消耗 CPU 的大戶(這些操做基本上都是 CPU 處理內存中的數據比較運算)。當咱們的 IO 優化作到必定階段以後,下降 CPU 計算也就成爲了咱們 SQL 優化的重要目標。
明確了優化目標以後,咱們須要肯定達到咱們目標的方法。對於 SQL 語句來講,達到上述2個目標的方法其實只有一個,那就是改變 SQL 的執行計劃,讓他儘可能「少走彎路」,儘可能經過各類「捷徑」來找到咱們須要的數據,以達到 「減小 IO 次數」 和 「下降 CPU 計算」 的目標。
1)儘可能少join:
MySQL 的優點在於簡單,但這在某些方面其實也是其劣勢。MySQL 優化器效率高,可是因爲其統計信息的量有限,優化器工做過程出現誤差的可能性也就更多。對於複雜的多表 Join,一方面因爲其優化器受限,再者在 Join 這方面所下的功夫還不夠,因此性能表現離 Oracle 等關係型數據庫前輩仍是有必定距離。但若是是簡單的單表查詢,這一差距就會極小甚至在有些場景下要優於這些數據庫前輩。
2)儘可能少排序:
排序操做會消耗較多的 CPU 資源,因此減小排序能夠在緩存命中率高等 IO 能力足夠的場景下會較大影響 SQL 的響應時間。對於MySQL來講,減小排序有多種辦法,好比:經過利用索引來排序的方式進行優化;減小參與排序的記錄條數;非必要不對數據進行排序。
3)儘可能避免select *:
select * 通常會形成全表掃描,顯示全部列,select須要的字段便可。
4)儘可能用join 代替子查詢:
雖然 Join 性能並不佳,可是和 MySQL 的子查詢比起來仍是有很是大的性能優點。MySQL 的子查詢執行計劃一直存在較大的問題,雖然這個問題已經存在多年,可是到目前已經發布的全部穩定版本中都廣泛存在,一直沒有太大改善。雖然官方也在很早就認可這一問題,而且承諾儘快解決,可是至少到目前爲止咱們尚未看到哪個版本較好的解決了這一問題。
5)儘可能用union all 代替union:
union 和 union all 的差別主要是前者須要將兩個(或者多個)結果集合並後再進行惟一性過濾操做,這就會涉及到排序,增長大量的 CPU 運算,加大資源消耗及延遲。因此當咱們能夠確認不可能出現重複結果集或者不在意重複結果集的時候,儘可能使用 union all 而不是 union。
6)禁用外鍵
7)避免大sql:
一個SQL只能在一個CPU上運行;高併發環境中,大SQL容易影響性能問題;可能一個大SQL把數據庫搞死;拆分SQL。
8)保持事務的短小精悍:
即開即用,用完即關;無關操做剔出事務,減小資源佔用;保持一致性的前提下,拆分事務。
9)避免大批量更新:
避開高峯,白天限制速度,加sleep。
10)避免類型轉換:
11)避免取過量數據,建議使用limit
12)避免在SQL語句中進行數學運算、函數計算、邏輯判斷等操做
13)避免OR:同一字段,推薦in;不一樣字段,推薦union。
14)優先優化高併發的SQL,而不是執行效率低的某些大SQL
15)從全局出發優化,而不是片面調整
16)儘量對每一條運行在數據庫中的SQL進行explain
17)優化要從整個業務邏輯上進行:
針對數據庫問題進行的優化,首先要考慮不查或少查數據庫。若是查詢不可避免,可考慮兩種優化方式:避免磁盤IO,讓查詢在內存中完成;經過sql和索引的調整,讓MySQL用更高效的方式查詢。索引設計原則:利用最左前綴、不要過分索引。
1)Spotlight on mysql
2)客戶端工具,有漂亮的ui界面,能夠監控到mysql的io、qcache、鏈接數、buffer pool等等,還有預警的功能
3)Lepus,一個開源的國產監控平臺,能夠監控到mysql的慢查詢、 qcache、鏈接數、buffer pool等等,能夠同時監控多臺,配置多個實例便可
4)Zabbix,也是一個開源的監控平臺,和lepus相似,配置比較複雜