基於索引層面mysql
1,覆蓋索引 實際上SELECT要查詢的數據都已經包含在索引中了(不 論是要查詢的列,仍是查詢的WHERE條件),這樣查詢能夠再也不在走表,減小查詢數據的次數sql
2,索引下推 好比where 條件爲 deptno like 'A%' and empno like 'B%' ,且當前有一個聯合索引爲(deptno,empno),那麼索引的執行會有兩種方式
1)根據deptno查找全部符合條件的記錄,根據mysql的二級索引須要回表查詢回相應行的方式回到取表全部的記錄,再根據empno的查詢要求檢索出相應的記錄
2)根據deptno查找全部符合條件的記錄,不回表直接從符合的結果再選出符合empno查詢要求的記錄,再回表讀取出數據。
mysql默認使用索引下推,目的在於減小回表查詢記錄的條數數據庫
3,最左前綴 當前建立聯合索引(deptno,empno)
數據庫中有記錄分別爲deptno,empno=[{10,11},{10,12},{11,21},{12,22},{30,31},{30,32}] 那麼當where 條件寫成 where deptno like '1%' and empno like '2%' 的時候。最左前綴的deptno條件會先取到知足條件的記錄範圍,再在這個範圍內讀取查詢相應的記錄。這個功能點要和MYSQL索引的B+樹結構聯繫。服務器
B+樹結構中各最終葉節點前有先後順序關聯,這個關聯特性有利於最左前綴的展開併發
4,不要在where條件中對某列進行進行函數計算 ,好比 where f(x)=y(z)+20 .由於對索引的利用至關因而去直接匹配索引中所保存的值進行對比比較。一旦引入的函數計算,就意味着要對每一個索引值都進行一次計算後才能肯定是否符合條件ide
5,索引儘可能包括group by ,order by 字句對應的列。 由於group by 與 order by 都會涉及到結果集的排序操做。尤爲當相應的結果集較大且SQL密集時會觸發臨時表空局內的大規模排序操做 好比在執行計劃中的extra列中能夠見到 file sorts提示 這種提示就意味着可能出現了排序操做,甚至會致使因SQL查詢出現數據庫鏈接中斷的狀況。在group by ,order by 對應的列上增長索引,利用索引的自然排序性減小或消除在列表空間中的排序操做。既減低SQL結果反饋的時間,又減輕對臨時表空間需求的壓力函數
6,對於刪除了大量數據或者插入數據的表,可使用OPTIMIZE TABLE的操做來從新對innodb表的主鍵進行物理層面上的調整性能
基於SQL書寫的
1,儘可能用UNION ALL 而不是UNION
UNION ALL 是簡單的返回結果集相加,不存在去重操做。而UNION 看起來簡單,反倒在結果集合並時進行了去重操做,對於不須要去重的查詢結果集,這等於多作了無謂操做,下降SQL效率測試
2,能用EXISTS儘可能不用IN,能用表關聯儘可能不用子查詢。優化
IN 只用於有肯定有限個參數值時使用好比 IN ('36','23','38') ,並且儘可能不要過百
IN EXISTS 和表關聯,大概來講都是各類形式的表關聯。當用了IN和EXISTS等在於在語境上告訴SQL解析器你必需要這種形式作表關聯,那麼SQL解析器將沒法發揮調優的做用。也就是說IN和EXISTS最好的執行狀況其實也和表關聯時SQL解析器分析出的通常結果差很少,不會比它好多少。至於IN和EXISTS間就不作區別說明了
基於慢查詢日誌定位慢查詢SQL根據執行計劃進行調優
在查詢慢SQL以前首先要定義一個合理的慢查詢SQL閾值,好比先定義2秒查詢返回的查詢是慢查詢。當先把這些慢查詢清理後再逐步壓低閾值,好比到300ms,再到100ms,分期分批,由緊至緩逐步推動
在檢索出來的慢查詢SQL中主要關注一下幾個指標
1,QUERY_TIME 最直觀的查詢時長
2,ROWS_EXAMINED 檢索了多少條記錄 若是where條件或者表聯接定義的很差,那麼對這個值的影響就會比較大
3,ROWS_SEND 結果集記錄的數量,若是查詢返回1W條,速度確定是比查詢返回1條要慢
查詢出慢SQL之後將相應的SQL對應的執行計劃打印出來,觀察執行計劃的狀況,有的放矢地進行調整
EXPLAIN select ………… 經過這種方式獲取相應的執行計劃
執行計劃中會包括 id,select_type,table,type,possible_keys,key,ken_len,ref,rows,extra等列
其中id列是一組數字,其表示的是這個SQL語句中每一個SQL單元執行的順序,當序號不一樣時大序號的單元先執行,小序號的單元后執行。當序號相同時排在上邊序號的單元先執行,下邊的後執行
好比 id 返回爲
1,
2,
3,
3,
4,
5,
那執行的順序爲 5,4,3(第3行) ,3(第4行),2,1
根據這個順序去逐一觀察整個SQL的執行步驟
select_type列表明每一個子句的類型,是比較簡單的仍是比較複雜的
simple 是最簡單的,沒有子查詢也沒有union, 最普通的where條件執行的結果
primary 說明有複雜的子部分,它的最外邊會被標記爲primary
subquery SQL中包含子查詢(能夠關注是否能夠性能調整)
DERIVED 衍生 本人理解爲 一大段SQL的結果我把它當成表來使用好比
select from a ,(select from b) c 這裏邊的(select * from b) 會觸發DERIVED 、
UNION 大SQL中存在對UNION 或者UNION ALL的使用,能夠關注是否有性能調整點
type列的取值範圍有all,index,range,ref,eq_ref,const,system null
all 全表掃描 通常來講在須要調優的複雜SQL中all的必需要調整掉,若是必要能夠增長相應的查詢條件,避免這種全表掃描
index 也是一種全表掃描,只是它是遍歷整個索引,而不是整個表
range:索引的範圍掃描,好比 deptno > 10 and deptno <30
ref:非唯一性索引掃描 好比對emp表寫SQL select * from emp where depnto = '2'
這裏的deptno 就是非唯一型索引列
eq_ref:唯一型索引列 好比對emp表寫SQL select * from emp where empno = '2'
const,system 當表裏只有一行的時候會有這種提示,到這個程度通常是不須要優化的
null:不訪問表也不訪問索引
經過執行計劃調優主要就是看這兩個列的狀況,儘可能減小最糟執行的出現
另外rows列也須要關注
rows列的數值很大可是執行很快的SQL,每每會是某個咱們在本地測試毫無壓力可是到服務器上卻致使業務變滿的根本緣由
本地很快是由於這種SQL在本地跑時因爲硬件資源許可因此速度很快。但在服務器上大量相同語句併發時可能會對系統的IO,BUFFER等資源形成爭用,致使性能急劇降低
extra列中主要須要關注是否有 files sort 或者 using temporary 若是有這種提示。那說明SQL會在臨表空間作排序,這個對SQL的查詢速度影響很大,同時也對臨表空間的壓力很大。若是存在問題考慮增長臨表空間,同時看看是否須要對排序或者group by 的列增長索引
另外還有基於DB參數的調整,之後整理