【问题标题】:SQL Query Costing, aggregating a view is faster?SQL Query Costing,聚合视图更快?
【发布时间】:2010-07-16 02:10:31
【问题描述】:

我有一个表 Sheet1$,其中包含 616 条记录。我有另一个表,Rates$,其中包含 47880 条记录。 Rates 包含从邮寄日期起 90 天内工作表中给定记录的响应率。在记录速率关系的所有 90 天内,总响应始终为 1 (100%)

例子:

Sheet1$: Record 1, 1000 QTY, 5% Response, Mail 1/1/2009

Rates$: Record 1, Day 1, 2% Response
        Record 1, Day 2, 3% Response
     Record 1, Day 90, 1% Response
     Record N, Day N, N Response

因此,我编写了一个视图,该视图采用这些表并将它们连接到费率的右侧以扩展数据,这样我就可以执行一些数学运算来获得任何给定记录的每日回报。

SELECT s.[Mail Date] + r.Day as Mail_Date, s.Quantity * s.[Expected Response Rate] * r.Response as Pieces, s.[Bounce Back Card], s.Customer, s.[Point of Entry]
  FROM Sheet1$ as s
 RIGHT OUTER JOIN Rates$ as r
            ON s.[Appeal Code] = r.Appeal
 WHERE s.[Mail Date] IS NOT NULL 
   AND s.Quantity <> 0 
   AND s.[Expected Response Rate] <> 0
   AND s.Quantity IS NOT NULL 
   AND s.[Expected Response Rate] IS NOT NULL);

所以我将它保存为一个名为 Test_Results 的视图。我使用 SQL Server Management Studio 运行此查询并获得 211,140 条记录的结果。经过时间为 4.121 秒,Est。子树成本为 0.751。

现在我对此视图运行查询以汇总每天的件数。

SELECT   Mail_Date, SUM(Pieces) AS Piececount
FROM     Test_Results
GROUP BY Mail_Date

这将返回 773 行,并且只需要 0.452 秒即可执行! 1.458 东部时间。子树成本。

我的问题是,以更高的估计,它是如何比原始视图本身执行得这么快的?!我会假设一块可能是它返回到管理工作室的行。如果是这种情况,我将如何在不考虑返回反馈的情况下查看此查询的真实成本?

【问题讨论】:

    标签: sql-server tsql query-optimization


    【解决方案1】:

    SELECT * FROM view1 会有一个计划

    SELECT * FROM view2(其中view2基于view1)会有自己的完整计划

    优化器足够聪明,可以让 view2 的计划将操作组合/折叠成最有效的操作。它只会观察 view1 设计的语义,但不一定需要使用 SELECT * FROM view1 的计划,而不是为 view2 应用另一个计划 - 通常,这将是一个完全不同的计划,并且它会尽其所能获得最有效的结果。

    通常,它将向下推聚合以提高选择性,并减少数据需求,这将加快操作速度。

    【讨论】:

      【解决方案2】:

      查询成本是无单位的,优化器仅使用它来选择它认为对特定查询最有效的执行路径。它们不能真正在查询之间进行比较。 This,虽然老了,但还是不错的速读。如果您真的感兴趣,您可能会想四处寻找有关 MSSQL 优化器和阅读查询计划的书籍或文章。

      (另外,请确保您查看的是实际执行计划,而不是解释计划……它们可能不同)

      【讨论】:

      • 这是来自实际的执行计划。此外,这不是我要比较的计划成本,而是所有数据的视图需要 4 秒,而针对该视图进行聚合的视图需要不到一秒的时间来执行......我假设它需要最初的成本加上汇总的时间,但这是我被挂断的地方
      • 有一点需要考虑……当您运行第一个查询时,缓存中的数据是什么?第二个呢?
      【解决方案3】:

      我认为 Cade 已经涵盖了最重要的部分 - 从视图中选择并不一定需要返回所有视图行,然后再针对它进行选择。 SQL Server 将优化整体查询。

      不过,要回答您的问题,如果您想避免网络和显示成本,那么您只需将每个查询结果选择到一个表中即可。只需在 SELECT 子句的列列表后添加“INTO Some_Table”即可。

      您还应该能够通过显示客户端统计信息或使用 Profiler 将事物分开,但 SELECT...INTO 方法既快速又简单。

      【讨论】:

        猜你喜欢
        • 2012-09-24
        • 2013-09-07
        • 1970-01-01
        • 2015-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-11
        相关资源
        最近更新 更多