如何优化 MySQL 视图
Posted
技术标签:
【中文标题】如何优化 MySQL 视图【英文标题】:How to optimize MySQL Views 【发布时间】:2009-06-20 09:40:43 【问题描述】:我有一些使用视图的查询,这些查询的运行速度比我预期的要慢很多,因为所有相关的表都已编入索引(而且不是那么大)。
我希望我能解释一下:
我的主要查询看起来像这样(非常简化)
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
Orders (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 意识到“这一切都比你想象的要简单,只要使用主键就可以了”?或者视图是完全错误的处理方式?
【问题讨论】:
【参考方案1】:如果可以删除这些连接,请将它们删除。用子查询替换它们会大大加快速度。
你也可以尝试运行这样的东西,看看它是否有任何速度差异。
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)
【讨论】:
我不认为您打算在子查询中包含“create view calc_order_status as”语句。我认为这是一个复制/粘贴错误。【参考方案2】:索引对于在大表中查找几行很有用,但是当您查询每一行时,索引只会减慢速度。所以这里 MySQL 可能希望使用整个 [order] 表,所以最好不要使用索引。
你可以试试forcingMySQL 使用索引会不会更快:
from orders as ord force index for join (yourindex)
【讨论】:
重读了这个有道理的问题。第 4 步是使用临时表,当然 [Orders] 上的索引对临时表无效。要使用索引,请重构查询,以便它在开始使用临时表之前执行连接。以上是关于如何优化 MySQL 视图的主要内容,如果未能解决你的问题,请参考以下文章
瞬间带你了解如何优化 Mysql 数据库,老板再也不担心客户投诉了
瞬间带你了解如何优化 Mysql 数据库,老板再也不担心客户投诉了