2012-01-01 41 views
1

我正在運行一系列測試以確定忽略索引如何影響查詢速度。以下是第一次測試系列的查詢字符串:索引提示和查詢執行計劃如何工作?

SELECT P.pid, P.name, P.cty, P.fla, P.pos, P.lvl, P.akP * E.usD AS 'ask' 
FROM Pig P 
IGNORE INDEX FOR JOIN (id_fla) // index is on fla (MEDIUMINT) column 
INNER JOIN Eel E ON E.cur = P.cur 
WHERE P.status IN ('a', 'l') AND P.fla >107 AND P.cDate >CURDATE() AND P.pos <45 
HAVING ask BETWEEN '50' AND '500' 
ORDER BY fla DESC 
LIMIT 100; 

在第二個測試系列,IGNORE INDEX FORJOIN被替換爲IGNORE INDEX FORORDER BY。並且在第三個測試系列中,IGNORE INDEX FOR ORDER BY被替換爲IGNORE INDEX FORGROUP BY

以下是測試結果和相應的查詢執行計劃。

試驗1(IGNORE INDEX FOR JOIN):

Query Number (n): 1 2 3 4 5 6 7 8 9 10 
Query Times (s): 90.6 0.13 27.2 21.4 0.11 0.10 29.8 27.8 0.17 6.56 
Rows Examined (k):26 26 36 43 37 37 58 85 66 98 

試驗2(忽略次序索引BY):

Query Number (n): 1 2 3 4 5 6 7 8 9 10 
Query Times (s): 90.7 0.14 26.5 21.2 0.10 0.11 35.0 28.5 0.17 6.64 
Rows Examined (k):26 26 36 43 37 37 58 85 66 98 

試驗3(IGNORE INDEX FOR GROUP BY ):

Query Number (n): 1 2 3 4 5 6 7 8 9 10 
Query Times (s): 263 10.1 10.1 9.95 9.94 10.1 10.0 9.95 9.96 10.1 
Rows Examined (M):4.18 4.18 4.18 4.18 4.18 4.18 4.18 4.18 4.18 4.18 
  • 注1:S - 秒,K - 數千中,M - 百萬
  • 注2:pos是唯一WHERE條件查詢之間變化 1〜10,條件WHERE恰好是 三者之間的相同測試每個查詢號碼。

試驗1(IGNORE INDEX FOR JOIN):

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: P 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 5000014 
     Extra: Using where 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: E 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 3 
      ref: BS.P.cur 
     rows: 1 
     Extra: 

試驗2(忽略次序索引BY)和試驗3(IGNORE INDEX FOR GROUP BY):

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: P 
     type: range 
possible_keys: id_flA 
      key: id_flA 
     key_len: 3 
      ref: NULL 
     rows: 4223660 
     Extra: Using where 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: E 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 3 
      ref: BS.P.cur 
     rows: 1 
     Extra: 

儘管測試2和測試3的查詢執行計劃與測試1相同並且不同,但查看的實際查詢速度和行似乎將測試1和d 2在一起。所以我有兩個問題,我需要問:

  1. 索引提示如何在這種情況下工作?
  2. 表掃描似乎在測試3上執行,但索引顯示爲 被使用。 MySQL是否遵循 EXPLAIN SELECT語句中的查詢執行計劃?
+0

索引提示可以試着幫什麼指標可以被應用於多個時被最好地應用到您的查詢優化器。也就是說,通過您提供的縮寫查詢,您能否提供完整的查詢,並確定「where」子句字段與哪個表相關聯。這些信息可能會更好地提供解決方案,以幫助您瞭解哪些索引可能對績效最佳......此外,您的查詢將執行的主要目的(條件)是什麼。 – DRapp 2012-01-02 14:41:35

+0

@DRapp:我有'fla'列一個簡單的指數,並在'pid'一個主鍵。 where子句全部與表格PIG相關聯。我修改了上面的查詢。可以看一下嗎? – 2012-01-02 15:11:01

回答

0
WHERE 
      P.status IN ('a', 'l') 
     AND P.fla > 107 
     AND P.cDate > CURDATE() 
     AND P.pos < 45 
    HAVING 
     ask BETWEEN '50' AND '500' 

您查詢本身看起來不錯(剛剛澄清從您的文章格式)。但是,如果您擁有的唯一索引是fla格式,那就是一個問題。索引應該基於你的查詢標準是基於...試圖更多地關注普通查詢條件,這些條件應該得到最小粒度來幫助優化..我不知道哪個更好......基於狀態,或基於cDate的條目,然後在fla和pos列上的位置。舉例來說,如果你有4首萬個條目,和500k的狀態是「A」,40萬爲狀態「L」,但只有20K用CDATE> CURDATE(),這將是你的索引的起點...指數在CDate上...然後添加下一個粒度級別。如果您有15個不同的狀態碼,那麼該cDate段中的每個狀態有多少個?但是在S/O上你比任何人都更瞭解你的數據,但是我會爲這個索引提出這個建議。在(狀態,CDATE,佛羅里達州,POS)

指數和嘗試,然後在(CDATE,狀態,佛羅里達州,pos。)的另一個指標,看看這有助於你的表現。 107以上有多少「fla」值?如果它的數量很少,那麼可能會把它作爲你的第一個索引限定詞,但我懷疑它是因爲你試圖不利用那個。

祝你好運,希望這可以幫助你想想你的數據多一點。

+0

我已經採用複合指數試過,但它不是有效由於'fla'和'pos'能夠覆蓋行,'cData'和'status'蓋最行的全部或沒有被值。 – 2012-01-03 02:09:22