2009-06-20 43 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