2017-09-29 93 views
0

什麼是適合這個查詢的索引。如何在Extra中優化MYSQL: - 使用where;使用臨時;使用filesort

我試圖給定索引的不同組合對於該查詢,但它仍然使用tempory使用,使用文件排序等

總表中的數據 - 7,60,346

product =「連衣裙」 - 總行數= 122 554

CREATE TABLE IF NOT EXISTS `product_data` (
    `table_id` int(11) NOT NULL AUTO_INCREMENT, 
    `id` int(11) NOT NULL, 
    `price` int(11) NOT NULL, 
    `store` varchar(255) NOT NULL, 
    `brand` varchar(255) DEFAULT NULL, 
    `product` varchar(255) NOT NULL, 
    `model` varchar(255) NOT NULL, 
    `size` varchar(50) NOT NULL, 
    `discount` varchar(255) NOT NULL, 
    `gender_id` int(11) NOT NULL, 
    `availability` int(11) NOT NULL, 
    PRIMARY KEY (`table_id`), 
    UNIQUE KEY `table_id` (`table_id`), 
    KEY `id` (`id`), 
    KEY `discount` (`discount`), 
    KEY `step_one` (`product`,`availability`), 
    KEY `step_two` (`product`,`availability`,`brand`,`store`), 
    KEY `step_three` (`product`,`availability`,`brand`,`store`,`id`), 
    KEY `step_four` (`brand`,`store`), 
    KEY `step_five` (`brand`,`store`,`id`) 
) ENGINE=InnoDB ; 

查詢:

SELECT id ,store,brand FROM `product_data` WHERE product='dresses' and 
availability='1' group by brand,store order by store limit 10; 

excu..time: - (10總計,查詢花費1.0941秒)

說明計劃:


possible_keys: - step_one,step_two,step_three,step_four,step_five

key: - step_two

ref: - 常量,常量

行: -

額外: - 使用其中;使用臨時;使用文件排序

我想這些指標


Key step_one(productavailability

Key step_two(productavailabilitybrandstore

Key step_three(productavailabilitybrandstoreid

Key step_four(brandstore

Key step_five(brandstoreid

+1

在你的問題中提供'SHOW CREATE TABLE product_data'輸出。 –

+1

@kuldeepupadhyay請給我們每個指標組合時的結果,你mentionned –

+0

@小寶答:是的,先生我的查詢挑選他們查詢花費1.0941秒 –

回答

1

真正的問題不是指數,而是防止服用LIMIT優勢GROUP BYORDER BY之間的不匹配。

INDEX(product, availability, store, brand, id) 

將 「覆蓋」,並以正確的順序。但請注意,我已經換storebrand ......

更改查詢

SELECT id ,store,brand 
    FROM `product_data` 
    WHERE product='dresses' 
     and availability='1' 
    GROUP BY store, brand -- change 
    ORDER BY store, brand -- change 
    limit 10; 

這改變了GROUP BY下手store,以反映ORDER BY排序 - 這避免額外的排序。並且它將ORDER BY更改爲與GROUP BY相同,以便兩者可以合併。

考慮到這些變化,INDEX現在可以一直到LIMIT,從而允許處理僅查看10行,而不是更大的集合。

任何小於所有這些變化的效率都不會那麼高。

進一步討論:

INDEX(product, availability, -- these two can be in either order 
     store, brand,  -- must match both `GROUP BY` and `ORDER BY` 
     id) -- tacked on (on the end) to make it "covering" 

「覆蓋」是指所有SELECT列在INDEX被發現,因此沒有必要將達到到數據。

但是... 整個查詢不會使因爲在SELECT列入id。如果你想找到有哪些商店有可用的禮服,那麼擺脫id。如果您想列出所有可用的連衣裙,請將id更改爲GROUP_CONCAT(id)

+0

謝謝先生,我明白你的觀點。 –

1

對於索引,最好索引是step_two。產品字段用於何處,並且與可用性字段相比具有更多的變體。

夫婦的關於查詢註釋:

  1. 可用性=「1」應該可用性=使得不必要內部 - > VARCHAR轉換將避免1。
  2. 「不應該將GROUP BY品牌」用作GROUP BY,只應在將聚合函數用作選定列時使用。你試圖通過團隊獲得什麼?
+0

是的先生我試過「SELECT ID,品牌」,但仍然使用tempory,使用filesort。請幫助 –

+0

你試圖通過小組達成什麼? – slaakso

1

如果沒有聚合函數,你的group by clause沒有意義。

如果您可以重新編寫查詢到

SELECT id ,store 
FROM `product_data` 
WHERE product='dresses' 
and availability='1' 
order by store limit 10; 

然後在(產品,可用性,)指數將刪除所有filesorts。

見SQLFiddle:http://sqlfiddle.com/#!9/60f33d/2

UPDATE:

的SQLFiddle讓您的意圖明顯 - 你用GROUP BY模擬DISTINCT。我不認爲你可以擺脫你的查詢中的filesort和臨時表步驟,如果是這樣的話 - 但我也不認爲這些步驟應該是非常昂貴的。

+0

父親請在這裏檢查http://sqlfiddle.com/#!9/5280b1/1 –

+1

這與原始請求不匹配,因爲它無法執行「GROUP BY」。 –

+1

「GROUP BY」在不存在聚集的情況下具有「DISTINCT」的效果。但是'DISTINCT'會偶然發現唯一的'id'。 –

相關問題