1. 程式人生 > >Mysql 語句執行順序

Mysql 語句執行順序

1.Mysql語法順序,即當sql中存在下面的關鍵字時,它們要保持這樣的順序:

select[distinct]  from   join   on  where  group by   having   union   order by    limit

2.Mysql執行順序,即在執行時sql按照下面的順序進行執行:

from

on

join

where

group by

having

select

distinct

union

order by

sql的執行順序對sql的效能優化很有幫助,是很重要的。在建立複合索引的時候需要考慮到這點。

舉一個例子:

在tb_student中建立一個複合索引 idx_school_grade:

 然後有兩個sql 看下解釋的結果:

1)在當前索引下,哪一個sql索引利用率高?

第一個sql執行的順序是先執行了 where後的 school_id 然後執行了 group by 後的 grade_id,順序是和索引的順序是一致的,type等級為ref

而第二個sql是先執行了 where後的 grade_id 然後執行了 group by 後的 school_id,順序是和索引的順序是不一致的,type等級為index,從解釋結果看,第一條的sql索引利用率高於第二條的。

2)怎麼優化

如果業務中用到第二個sql,那麼就需要調整索引的順序和sql執行順序一致。

通過explain可以知道mysql是如何處理語句,分析出查詢或是表結構的效能瓶頸。通過expalin可以得到:

1. 表的讀取順序 2.表的讀取操作的操作型別 3.哪些索引可以使用 4. 哪些索引被實際使用 5.表之間的引用 6.每張表有多少行被優化器查詢

Id: MySQL QueryOptimizer 選定的執行計劃中查詢的序列號。表示查詢中執行select 子句或操作表的順序,id 值越大優先順序越高,越先被執行。id 相同,執行順序由上至下。  

Select_type:一共有9中型別,只介紹常用的4種:

         SIMPLE: 簡單的 select 查詢,不使用 union 及子查詢

          PRIMARY: 最外層的 select 查詢

          UNION: UNION 中的第二個或隨後的 select 查詢,不 依賴於外部查詢的結果集

          DERIVED: 用於 from 子句裡有子查詢的情況。 MySQL 會 遞迴執行這些子查詢, 把結果放在臨時表裡。

Table:輸出行所引用的表

 Type: 從有到差的順序如下:

System-->const-->eq_ref-->ref-->ref_or_null-->index_merge-->unique_subquery-->index_subquery-->range-->index-->all.

各自的含義如下:

system:  表僅有一行(=系統表)。這是 const 連線型別的一個特例。

const:  const 用於用常數值比較 PRIMARY KEY 時。當 查詢的表僅有一行時,使用 System。

eq_ref: 從前面的表中,對每一個記錄的聯合都從表中讀取一個記錄,它在查詢使用了索引為主鍵或惟一鍵的全部時使用

ref:  連線不能基於關鍵字選擇單個行,可能查詢 到多個符合條件的行。 叫做 ref 是因為索引要 跟某個參考值相比較。這個參考值或者是一個常數,或者是來自一個表裡的多表查詢的 結果值。

ref_or_null:  如同 ref, 但是 MySQL 必須在初次查詢的結果裡找出 null 條目,然後進行二次查詢。

index_merge: 說明索引合併優化被使用了。

unique_subquery:  在某些 IN 查詢中使用此種類型,而不是常規的 ref:valueIN (SELECT primary_key FROM single_table WHERE some_expr)

index_subquery:  在 某 些 IN 查 詢 中 使 用 此 種 類 型 , 與unique_subquery 類似,但是查詢的是非唯一 性索引

range:  只檢索給定範圍的行,使用一個索引來選擇 行。key列顯示使用了哪個索引。當使用=、 <>、>、>=、<、<=、IS NULL、<=>、BETWEEN 或者 IN 操作符,用常量比較關鍵字列時,可 以使用 range。

index:  全表掃描,只是掃描表的時候按照索引次序 進行而不是行。主要優點就是避免了排序, 但是開銷仍然非常大。

all: 最壞的情況,從頭到尾全表掃描。

possible_keys : 指出能在該表中使用哪些索引有助於 查詢。如果為空,說明沒有可用的索引。

key:實際從 possible_key 選擇使用的索引。 如果為 NULL,則沒有使用索引。很少的情況 下,MYSQL 會選擇優化不足的索引。這種情 況下,可以在 SELECT語句中使用 USE INDEX (indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制 MYSQL 忽略索引

key_len:  使用的索引的長度。在不損失精確性的情況 下,長度越短越好。

ref:  顯示索引的哪一列被使用了 

rows:   認為必須檢查的用來返回請求資料的行數

extra: 中出現以下 2 項意味著  根本不能使用索引,效率會受到重大影響。應儘可能對此進行優化。

Using filesort: 表示 會對結果使用一個外部索引排序,而不是從表裡按索引次序讀到相關內容。可能在記憶體或者磁碟上進行排序。無法利用索引完成的排序操作稱為“檔案排序”

Using temporary:表示對查詢結果排序時使用臨時表。常見於排序 order by 和分組查詢group by。 

其中重要的幾個就是 key、type 、rows、extra,其中key為null時,說明沒有使用到索引,需要調整索引,type為all的地方,都是需要進行優化的地方.一般需要達到 ref級別,範圍查詢需要達到 range,extra有Using filesort、Using temporary 的一定需要優化,根據rows可以直觀看出優化結果。