2011-03-22 283 views
2

我試圖優化在電子商務網站上運行的報表查詢。我敢肯定,我正在做一些愚蠢的事情,因爲這個查詢不應該花費盡可能長的時間來運行。 有問題的查詢:MYSQL查詢優化

SELECT inventories_name, inventories_code, SUM(shop_orders_inventories_qty) AS qty, 
SUM(shop_orders_inventories_price) AS tot_price, inventories_categories_name, 
inventories_price_list, inventories_id 
FROM shop_orders 
LEFT JOIN shop_orders_inventories ON (shop_orders_id = join_shop_orders_id) 
LEFT JOIN inventories ON (join_inventories_id = inventories_id) 
WHERE {$date_type} BETWEEN '{$start_date}' AND '{$end_date}' 
AND shop_orders_x_response_code = 1 
GROUP BY join_inventories_id, join_shop_categories_id 
{$order} 
{$limit} 

它基本上是試圖在一段時間來獲得每個項目的總銷售額;大括號中的值通過表單填寫。它可以在幾天內正常工作,但是查詢一週或更長的時間間隔可能需要30秒+。

我覺得爲了計算聚合值並吸取大量內存,我覺得它加入了太多的行,但我不知道如何限制它。

注 - 我意識到我選擇的字段不在羣組中,但它們與羣組中的庫存ID相對應。

有什麼建議嗎?

- 編輯 - 目前的指標是:
庫存:
join_categories - BTREE
inventories_name,inventories_code,inventories_description - FULLTEXT

shop_orders_inventories:
shop_orders_inventories_id - BTREE

shop_orders:
shop_orders_id - BTREE

+0

這些表有哪些索引? – 2011-03-22 23:00:57

回答

2

兩個連續左同步加入相當長的將工作在一個大桌子。嘗試使用「join」而不是「left join」(除非您在shop_orders中有記錄,現在在shop_orders_inventories或清單中匹配記錄)或將此查詢拆分爲幾個小記錄。另外,通過使用「sum」和「group by」,你迫使MySQL創建臨時表 - 你可能想增加MySQL緩存,以便這些表適合內存(否則MySQL會將它們轉儲到磁盤,這也會增加SQL執行時間)。

+0

優秀的建議 - 從左連接切換到加入顯着提升性能 – 2011-03-22 23:16:52

1

編制索引的第一條和最重要的規則是...索引您要搜索的列!

對於{$ date_type}的每個可能值,請爲該日期列創建一個索引。

一旦你在表格中有很多數據(比如2年或100周),一週的數據就是索引的1%,所以它成爲一個很好的起點。

即使MySQL允許非聚集SELECT子句中,我個人兩個

SELECT inventories_name, inventories_code, 
     SUM(shop_orders_inventories_qty) AS qty, 
     SUM(shop_orders_inventories_price) AS tot_price, 
     inventories_categories_name, inventories_price_list, inventories_id 
FROM ... 
GROUP BY inventories_id, join_shop_categories_id, inventories_name, 
     inventories_code, inventories_categories_name, inventories_price_list 
...