我有一些使用视图的查询,并且这些查询的运行速度比我预期的要快得多,因为所有相关的表都被编入索引(并且不管那么大)。
我希望我能解释一下:
我的主要查询看起来像这样(非常简化)
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
包含与每个订单及其价格相关联的各个商品。
所有表格都已正确编入索引,但事情运行缓慢,当我执行EXPLAIN时,我得到了
# 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 on(ors.order _ id = ord.id) 和ord.id(在主查询和视图中)都引用主键。
我已经阅读过某些地方而不是MySQL simpliy没有很好地优化视图,即使在可用的情况下也可能无法在某些条件下使用密钥。这似乎是其中一种情况。
我将不胜感激任何建议。有没有办法迫使MySQL意识到“它比你想象的更简单,只需使用主键就可以了”?或者观点是错误的方式来解决这个问题?
答案 0 :(得分: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)
答案 1 :(得分:0)
索引对于在大表中查找几行很有用,但是当您查询每一行时,索引只会减慢速度。所以这里MySQL可能希望使用整个[order]表,所以最好不要使用索引。
你可以试试forcing MySQL使用索引会更快:
from orders as ord force index for join (yourindex)