使用聚合函数优化 MySQL 视图
Posted
技术标签:
【中文标题】使用聚合函数优化 MySQL 视图【英文标题】:Optimizing MySQL View with aggregate function 【发布时间】:2012-12-08 08:27:59 【问题描述】:我有这样的看法:
CREATE VIEW invoicereport
SELECT i.ID, SUM(o.Amount * o.Price) AS Total
FROM invoice i
JOIN `order` o ON i.ID = o.InvoiceID
GROUP BY i.ID
直接运行此查询需要 0.03 秒。
但是运行视图需要 2 秒。即使我这样做 SELECT * FROM invoicereport WHERE ID=9000
仍然需要 2 秒。
所以我将视图重写为:
CREATE VIEW invoicereport
SELECT i.ID, (SELECT SUM(Amount * Price) FROM `order` WHERE InvoiceID=i.ID) AS Total
FROM invoice i
认为子查询只会针对 ID 9000 执行。
然后当我执行SELECT * FROM invoicereport WHERE ID=9000
时,它会更慢,需要 3 秒才能完成。
还有其他方法可以优化这个查询吗?
【问题讨论】:
mysql VIEW as performance troublemaker 【参考方案1】:我认为没有必要加入这些表,只需分组 order
就足够了。 (只是我的观点)。像这样:
CREATE VIEW INVOICEREPORT
SELECT O.INVOICEID as ID, SUM(O.AMOUNT * O.PRICE) AS TOTAL
FROM `ORDER` O
GROUP BY O.INVOICEID
然后你可以和其他人一起加入这个视图。并在order
上使用索引。
【讨论】:
表格发票包含客户姓名、电话等其他信息 试试这样:select i.id, i.customer_name, i.tel, ir.total from invoice i join invoicereport ir on ir.id = i.id
【参考方案2】:
我同意 Kuya John 的评论。在这样一个简单的总结中,甚至都不要试图将其作为一个视图来做。它的简单性是不需要进行连接的。几年前我提供了另一个类似的答案,其中有人正在使用现有视图,而他的查询是一些淫秽的时间。当我要求返回查询的原始表并直接编写时,查询仍然非常简单易读且速度极快。不要使用视图,只需直接选择语句即可。
像子选择这样的视图是典型的查询时间杀手,我尽量避免它们。
由于您也在寻找其他发票数据,所以应该没有问题......但更大的确认......您的订单表是否有关于发票 ID 的索引?
SELECT
I.ID,
I.Customer_Name,
I.Tel,
SUM(o.Amount * o.Price) AS Total
FROM
invoice I
JOIN `order` o ON I.ID = O.InvoiceID
WHERE
I.ID = 9000
GROUP BY
I.ID
【讨论】:
InvoiceID 是一个索引。实际查询也比这复杂得多,它包含 COUNT(o.ID) AS OrderCount, SUM(IF(mg.Type='Food',1,0)) AS FoodCount, SUM(IF(mg.Type= 'Drink',1,0)) AS DrinkCount 等,order
加入了 menu
加入了 menugroup
以上是关于使用聚合函数优化 MySQL 视图的主要内容,如果未能解决你的问题,请参考以下文章