2

我有一些使用视图的查询,这些查询的运行速度比我预期的要慢得多,因为所有相关的表都已编入索引(而且不是那么大)。

我希望我能解释一下:

我的主要查询看起来像这样(大大简化)

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 已经定义:left join calc_order_status as ors on (ors.order _ id = ord.id) 和 ord.id(在主查询和视图内)指的是主键.

我在某处读过 MySQL 简单并没有很好地优化视图,并且即使在可用的情况下也可能在某些条件下不使用键。这似乎是其中一种情况。

我将不胜感激任何建议。有没有办法让 MySQL 意识到“这一切都比你想象的要简单,只要使用主键就可以了”?或者意见是完全错误的方式吗?

4

2 回答 2

4

如果完全可以删除这些连接,请将它们删除。用子查询替换它们会大大加快速度。

你也可以尝试运行这样的东西,看看它是否有任何速度差异。

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) 
于 2009-06-24T17:09:33.380 回答
0

索引对于在大表中查找几行很有用,但是当您查询每一行时,索引只会减慢速度。所以这里 MySQL 可能希望使用整个 [order] 表,所以最好不要使用索引。

您可以通过强制MySQL 使用索引来尝试是否会更快:

from orders as ord force index for join (yourindex)
于 2009-06-20T11:14:37.990 回答