2009-06-20 85 views
2

我有一些使用視圖的查詢,而且這些運行速度比我預期的要慢得多,因爲所有相關的表都被編入索引(而且不管那麼大)。如何優化MySQL視圖

我希望我可以解釋這一點:

我的主要查詢看起來是這樣的(非常簡化的)

select [stuff] from orders as ord 
left join calc_order_status as ors on (ors.order_id = ord.id) 

calc_order_status一種觀點,正是如此定義:

create view calc_order_status as 
select ord.id AS order_id, 
(sum(itm.items * itm.item_price) + ord.delivery_cost) AS total_total 
from orders ord 
left join order_items itm on itm.order_id = ord.id 
group by ord.id 

訂單(ORD )包含訂單,order_items包含與每個訂單及其價格相關的單個項目。

所有表正確索引,但事情運行緩慢,當我做一個解釋,我得到

# id select_type table type possible_keys key key_len ref rows Extra 
    1 1 PRIMARY ord ALL customer_id NULL NULL NULL 1002 Using temporary; Using filesort 
    2 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 1002 
    3 1 PRIMARY cus eq_ref PRIMARY PRIMARY 4 db135147_2.ord.customer_id 1 Using where 
    4 2 DERIVED ord ALL NULL NULL NULL NULL 1002 Using temporary; Using filesort 
    5 2 DERIVED itm ref order_id order_id 4 db135147_2.ord.id 2 

我的猜測是,「Derived2的」是指視圖。單個項目(itm)似乎工作正常,通過order _id索引。問題似乎是第4行,這表明系統沒有爲訂單表(ord)使用密鑰。但是在MAIN查詢中,已經定義了訂單ID: 左連接calc_order_status作爲ors(ors.order_id = ord.id) 和ord.id(在主查詢和視圖內)參考首要的關鍵。

我讀過的地方不是MySQL simpliy沒有優化視圖,並且在某些情況下可能無法利用密鑰,即使可用。這似乎是其中的一種情況。

我將不勝感激任何建議。有沒有辦法強制MySQL實現「這比你想象的更簡單,只需使用主鍵,你就會好起來的」?或者是觀點錯誤的方式去做這件事?

回答

4

。用subquerys替換它們會加速很多。

你也可以嘗試運行這樣的東西,看看它是否有任何速度差異。

select [stuff] from orders as ord 
left join (
    create view calc_order_status as 
    select ord.id AS order_id, 
    (sum(itm.items * itm.item_price) + ord.delivery_cost) AS total_total 
    from orders ord 
    left join order_items itm on itm.order_id = ord.id 
    group by ord.id 
) as ors on (ors.order_id = ord.id) 
0

索引對於在大表中查找幾行非常有用,但是當您查詢每一行時,索引只會減慢速度。所以這裏MySQL可能期望使用整個[order]表,所以最好不要使用索引。

你可以嘗試,如果這將是更快地forcing MySQL使用一個索引:如果可能的話,以消除那些連接刪除它們

from orders as ord force index for join (yourindex) 
+1

不會做詭計...... – jms 2009-06-21 08:11:10

+0

重讀這個問題後,纔有意義。第4步是使用臨時表,當然[訂單]上的索引對臨時表無效。要使用索引,請重構查詢,以便在開始使用臨時表之前完成連接。 – Andomar 2009-06-21 12:01:11