我怎样才能加快这个汇总报价行行负载的视图?

Posted

技术标签:

【中文标题】我怎样才能加快这个汇总报价行行负载的视图?【英文标题】:How can I speed up this view which sums a load of quote line rows? 【发布时间】:2011-01-31 23:37:41 【问题描述】:

我正在编写一个视图来显示基于对报价行表中的值求和的报价总计。我需要将视图限制为仅显示特定“价格类型”客户的报价。但是,当我这样做时,视图会变慢很多。

对价格求和的 SQL

SELECT dbo.quoteline.qid, SUM((dbo.pricelist.listprice - dbo.quoteline.voff) * dbo.quoteline.quantity) AS total
FROM dbo.quoteline LEFT OUTER JOIN dbo.pricelist ON dbo.quoteline.prodcode = dbo.pricelist.prodcode GROUP BY dbo.quoteline.qid

添加“pricetype”约束后的 SQL

SELECT     dbo.quoteline.qid, SUM((dbo.pricelist.listprice - dbo.quoteline.voff) * dbo.quoteline.quantity) AS total
FROM         dbo.pricelist RIGHT OUTER JOIN
                      dbo.client RIGHT OUTER JOIN
                      dbo.quote ON dbo.client.cid = dbo.quote.cid RIGHT OUTER JOIN
                      dbo.quoteline ON dbo.quote.qid = dbo.quoteline.qid ON dbo.pricelist.prodcode = dbo.quoteline.prodcode
WHERE     (dbo.client.pricetype = 'V')
GROUP BY dbo.quoteline.qid

也许已经晚了,我有一点时间,但我们将不胜感激。

【问题讨论】:

需要查看你的表和索引定义... 好的,向您展示这些内容的最佳方式是什么?把所有的桌子设计贴在这里(抱歉第一次发帖,所以只是学习)。 【参考方案1】:

两件事:首先,您能否在 dbo.client.pricetype 列上放置一个索引而不干扰插入/更新?其次,内部联接通常比外部联接快,并且由于您的结果和 where 子句取决于其他表,我怀疑您无论如何都会想要进行内部联接,除非您需要从视图中返回 NULL 记录。试试下面的查询,看看它是否能得到你需要的结果:

SELECT dbo.quoteline.qid, SUM((dbo.pricelist.listprice - dbo.quoteline.voff) * dbo.quoteline.quantity) AS total
FROM dbo.quoteline 
INNER JOIN dbo.pricelist ON dbo.quoteline.prodcode = dbo.pricelist.prodcode 
INNER JOIN dbo.quote ON dbo.quote.qid = dbo.quoteline.qid 
INNER JOIN dbo.client ON dbo.client.cid = dbo.quote.cid 
WHERE     (dbo.client.pricetype = 'V')
GROUP BY dbo.quoteline.qid

【讨论】:

嗨 nybbler,此查询返回相同的正确结果集,但似乎根本没有加快速度。我也在 pricetype 字段上放置了一个索引。是否与有多个连接以从我们对行求和的报价行表返回 pricetype 字段有关? @Rob 如果您用于连接的表中的列没有被索引,那肯定会影响查询。即quote.qidquoteline.qidclient.cidquote.cidquoteline.prodcodepricelist.prodcode。我维护的遗留系统比这运行良好的连接要求更高。如果您使用的是 MSSQlServer,估计的执行计划也可以为您推荐一些需要改进的地方。 我在所有 pk 和 fk 列上都有索引...也许我会尝试估计的执行计划(以前从未听说过) @Rob:关于如何阅读估计执行计划的快速教程可以在这里找到:sqlserverpedia.com/wiki/Examining_Query_Execution_Plans让我知道它是怎么回事 好吧,看来我已经想通了。在 pricelist 表中的 prodcode 列中添加了索引。那里有 300k 行!感谢您对此@nybbler 的帮助【参考方案2】:

如果你这样做会发生什么:

SELECT     dbo.quoteline.qid, SUM((dbo.pricelist.listprice - dbo.quoteline.voff) * dbo.quoteline.quantity) AS total
FROM         dbo.pricelist RIGHT OUTER JOIN
                      dbo.client ON dbo.client.pricetype = 'V' RIGHT OUTER JOIN
                      dbo.quote ON dbo.client.cid = dbo.quote.cid RIGHT OUTER JOIN
                      dbo.quoteline ON dbo.quote.qid = dbo.quoteline.qid AND dbo.pricelist.prodcode = dbo.quoteline.prodcode
GROUP BY dbo.quoteline.qid

【讨论】:

@Rob, FranciscoSoto:最后一个连接中的第二个 ON 应该是 AND 感谢那个 nybbler。这个查询快了很多,但是它返回了一些空值的行?! 哦,是的,我只是注意到客户端上的完全连接,后来没有注意到语法错误。 @Rob:将右外连接更改为内连接,除非您特别需要其他表中的空行。

以上是关于我怎样才能加快这个汇总报价行行负载的视图?的主要内容,如果未能解决你的问题,请参考以下文章

双连接查询需要 540 秒才能运行 - 我怎样才能加快速度?

收到通知后,我如何才能在应用程序图标点击时获得有效负载?

我怎样才能更早地呼叫运输人员?

我怎样才能加快这个迭代?

我怎样才能加快这个 Anagram 算法

SQLite3-我怎样才能加快这个 SELECT 查询?