MySql語句執行過程(從結構看優化)

邏輯查詢步驟數據庫

查詢操做是關係數據庫中使用最爲頻繁的操做,也是構成其餘MySQL語(如DELETE、UPDATE)的基礎。查詢處理的順序以下:優化

(7) SELECT (8) DISTINCT 
(1) FROM 
(3) JOIN 
(2) ON 
(4) WHERE 
(5) GROUP BY 
(6) HAVING 
(9) ORDER BY 
(10) LIMITspa

1)FROM:對FROM子句中的左表和右表執行笛卡兒積(Cartesian product),產生虛擬表VT1。 
2)ON:對虛擬表VT1應用ON篩選,只有那些符合的行才**入虛擬表VT2中。 
3)JOIN:若是指定了OUTER JOIN(如LEFT OUTERJOIN、RIGHT OUTER JOIN),那麼保留表中未匹配的行做爲外部行添加到虛擬表VT2中,產生虛擬表VT3。若是FROM子句包含兩個以上表,則對上一個鏈接生成的結果表VT3和下一個表重複執行步驟1)~步驟3),直處處理完全部的表爲止。 
4)WHERE:對虛擬表VT3應用WHERE過濾條件,只有符合的記錄才**入虛擬表VT4中。此時數據尚未分組,因此不能在where中出現對統計的過濾 
5)GROUP BY:根據GROUP BY子句中的列,對VT4中的記錄進行分組操做,產生VT5。在GROUP BY階段,數據庫認爲兩個NULL值是相等的,所以會將NULL值分到同一個分組中。 
6)CUBE|ROLLUP:對錶VT5進行CUBE或ROLLUP操做,產生表VT6。 
7)HAVING:對虛擬表VT6應用HAVING過濾器,只有符合的記錄才**入虛擬表VT7中。count(expr) 會返回expr不爲NULL的行數,count(1)、count(*)會返回包括NULL值在內的全部數量 
8)SELECT:第二次執行SELECT操做,選擇指定的列,插入到虛擬表VT8中。 
9)DISTINCT:去除重複數據,產生虛擬表VT9。 
10)ORDER BY:將虛擬表VT9中的記錄按照進行排序操做,產生虛擬表VT10。若是不指定排序,數據並不是老是按照主鍵順序進行排序的。NULL被視爲最小值 
11)LIMIT:取出指定行的記錄,產生虛擬表VT11,並返回給查詢用戶。LIMIT n, m的效率是十分低的,通常能夠經過在where條件中指定範圍來優化 where id> ? limit 10blog

物理查詢排序

數據庫也許並不會徹底按照邏輯查詢處理的方式來進行查詢,MySQL數據庫層有Parser和Optimizer兩個組件。Parser的工做就是分析SQL語句,而Op-timizer的工做就是對這個SQL語句進行優化,選擇一條最優的路徑來選取數據,可是必須保證物理查詢處理的最終結果和邏輯查詢處理是相等的。遞歸

Explain語句簡介索引

explain命令是查看查詢優化器(Optimizer)是如何執行查詢語句的。ci

explain輸出字段get

idit

select_type

table

type

possible_keys

key

key_len

ref

rows

Extra

id 
id值越大優先級越高,越先被執行。id相同時,執行順序由上至下。

select_type 
**:意味着查詢不包括子查詢和union

PRIMARY:查詢中若包含任何複雜的子部分,最外層的select被標記爲PRIMARY 
SUBQUERY: 包含在SELECT列表中的子查詢中的SELECT(不在From字句中) 
DERIVED:包含在FROM子句的子查詢中的SELECT,MySQL會遞歸執行並將結果放到一個臨時表中。 
UNION: UNION中的第二個或後面的SELECT語句,UNOIN中的第一個SELECT顯示爲PRIMARY。 
UNION RESULT:用來從UNION的匿名臨時表檢索結果的SELECT被標記爲UNION SELECT。

table 
顯示這一行數據正在訪問哪張表,若在查詢中爲select起了別名,則顯示別名,若是爲(x是個數字,能夠理解爲第幾步執行的結果)

type 
ALL: 全表掃描,MySQL將遍歷全表以找到匹配的行。 
index: 跟ALL同樣,只是掃描全表時按索引次序進行,與ALL相比主要優勢是避免了排序。 
range: 有限制的索引掃描,帶有BETWEEN 或在WHERE字句中帶有>、<的查詢。 
ref: 索引查找,查找索引匹配某個單值的全部行(當索引爲非惟一性索引時)。 
eq_ref: 相似ref,區別就在使用的索引是惟一索引,對於每一個索引鍵值,表中只有一條記錄匹配,簡單來講,就是多表鏈接中使用primary key或者 unique key做爲關聯條件。 
const、system: const用於用常數值比較PRIMARY KEY或UNIQUE索引的全部部分時,system是const類型的特例,當查詢的表只有一行的狀況下,使用system。 
NULL: MySQL在優化過程當中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列裏選取最小值能夠經過單獨索引查找完成。

possible_keys 
查詢可使用哪些索引。

keys 
MySQL實際採用哪一個索引。

key_len 
表示索引中使用的字節數,可經過該列計算查詢中使用的索引的長度(key_len顯示的值爲索引字段的最大可能長度,並不是實際使用長度,即key_len是根據表定義計算而得,不是經過表內檢索出的) 
不損失精確性的狀況下,長度越短越好

ref 
使用哪一個列或常數與key一塊兒從表中選擇行。

rows 
MySQL估計爲了找到所需的行而要讀取的行數。

Extra 
Using index: 從索引中就能夠查詢到最終須要的信息,不須要再讀取表。 
Using temporary: 表示MySQL須要使用臨時表來存儲結果集,常見於排序和分組查詢 
Using filesort: MySQL中沒法利用索引完成的排序操做稱爲」文件排序」

原文來自:shanks’s blog

相關文章
相關標籤/搜索