2016-11-02 168 views
0

我在運行MySQL的查詢時遇到問題。感謝您的幫助,瞭解如何進行優化。SQL查詢需要的時間太長 - 臨時表

討論中的查詢表上運行約8000行,看起來像這樣:

price_id int(5) Primary Key with auto increment 
product_id int(5) 
price_amount float 
price_date date 

基本上,它擁有的幾款產品的歷史價格,這樣就可以生成相關的任何歷史性的日子發票。

有問題的查詢必須提供與特定日期相關的產品列表的最新價格。例如,獲得的product_id 1,2和4,以9月1日的相關價格,這將是:

SELECT * 
FROM prices 
WHERE price_id IN (
    SELECT max(prices.price_id) 
    FROM prices 
    WHERE product_id in (1,2,4) AND price_date <= '2016-09-01' 
    GROUP BY product_id 
) 

現在,這個查詢aaaaaages運行。它有所不同,但現在,例如,對於3個product_ids,運行大約需要58秒。通常情況下,發票有大約120〜產品在他們(需要幾分鐘的時間才能返回結果),所以你可以想像的麻煩..

我異形在phpMyAdmin查詢,基本上它看起來像這樣:

Status      Time 
Sorting result    0.000050 
Sending data     0.000025 
executing      0.000009 
Copying to tmp table   0.008586 
Sorting result    0.000052 
Sending data     0.000026 
executing      0.000006 
Copying to tmp table   0.008118 
Sorting result    0.000057 
Sending data     0.000029 
executing      0.000011 
Copying to tmp table   0.007498 
Sorting result    0.000047 
Sending data     0.000021 
executing      0.000005 
Copying to tmp table   0.008479 
Sorting result    0.000056 
Sending data     0.000031 
executing      0.000011 
Copying to tmp table   0.007371 
Sorting result    0.000059 
Sending data     0.000031 
executing      0.000011 
Copying to tmp table   0.006702 
Sorting result    0.000045 
Sending data     0.000019 
executing      0.000005 
Copying to tmp table   0.005319 
Sorting result    0.000034 
Sending data     0.000015 
executing      0.000005 
Copying to tmp table   0.005302 
Sorting result    0.000035 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005207 
Sorting result    0.000031 
Sending data     0.000014 
executing      0.000005 
Copying to tmp table   0.005243 
Sorting result    0.000034 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005236 
Sorting result    0.000035 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005185 
Sorting result    0.000035 
Sending data     0.000015 
executing      0.000005 
Copying to tmp table   0.005256 
Sorting result    0.000033 
Sending data     0.000017 
executing      0.000005 
Copying to tmp table   0.005160 
Sorting result    0.000025 
Sending data     0.000014 
executing      0.000005 
Copying to tmp table   0.005149 
Sorting result    0.000024 
Sending data     0.000013 
executing      0.000005 
Copying to tmp table   0.005356 
Sorting result    0.000038 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005221 
Sorting result    0.000034 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005189 
Sorting result    0.000033 
Sending data     0.000015 
executing      0.000005 
Copying to tmp table   0.005370 
Sorting result    0.000038 
Sending data     0.000017 
executing      0.000005 
Copying to tmp table   0.005208 
Sorting result    0.000035 
Sending data     0.000017 
executing      0.000006 
Copying to tmp table   0.005209 
Sorting result    0.000036 
Sending data     0.000054 
end       0.000019 
removing tmp table   0.000021 
end       0.000008 
query end      0.000006 
closing tables    0.000020 
freeing items     0.000052 
Waiting for query cache lock 0.000006 
freeing items     0.000852 
Waiting for query cache lock 0.000012 
freeing items     0.000004 
storing result in query cache 0.000019 
logging slow query   0.000005 
logging slow query   0.000010 
cleaning up     0.000009 

Showing rows 0 - 2 (3 total, Query took 58.6074 sec) 

所以我想通過數字猜測,大部分時間都花在創建臨時表格上。 (最大堆和臨時表大小參數都是16M的默認值)。

有沒有人有任何想法如何我可以加快這個查詢或設計一個新的查詢,但做得更好,但效率更高?

+0

查詢優化和關係代數! –

回答

0

嘗試使用從(一DINAMIC)和所得到的表

select * from prices as a 
    inner join (  
     SELECT max(prices.price_id) as max_price_id 
     FROM prices 
     WHERE product_id in (1,2,4) AND price_date <= '2016-09-01' 
     GROUP BY product_id) t on t.max_price_id = a.price_id 
0

使用相關查詢內部聯接,有時MySQL已經在子查詢的問題

SELECT prices.* 
FROM prices 
WHERE EXISTS (
    SELECT max(p.price_id) 
    FROM prices p 
    WHERE p.product_id in (1,2,4) AND p.price_date <= '2016-09-01' 
    AND prices.price_id = p.price_id 
    GROUP BY p.product_id 
) 
0

,如果你是自由的添加索引,通過(1)product_id,(2)price_date(降序)索引表,並且您可以執行以下操作:

SELECT * 
FROM prices 
WHERE product_id in (1,2,4) AND price_date <= '2016-09-01' 
ORDER BY price_date DESC 
LIMIT 1 
+0

不會只返回一個產品嗎?我們需要所有三種產品的價格 – Odesh