【问题标题】:Correlated subquery performance相关子查询性能
【发布时间】:2012-03-23 13:37:03
【问题描述】:

我在我的一个存储过程中发现了一个瓶颈查询。 @Results 是具有约 17K 行的表变量。它包括一个时间戳(日期时间)列和一个值(十进制)列。

相关子查询方法是我首先想到的完成这项任务的方法,但性能非常差。除了使用针对同一个表的相关子查询“计算” WHERE 子句之外,我想不出更好的方法来构造这个查询。关于如何写得更好的任何建议......

我基本上是在尝试从完整结果的子集中选择最高值。现在,通过计算小于或等于该值的所有值、将其乘以 100、除以 @Count,并查看它是否大于某个百分比,结果记录被包含在子集中。

这是查询:

SELECT TOP 1 @Result = Results.Value
FROM @Results Results
WHERE (100.0 * (SELECT COUNT(1) 
                FROM @Results Results2
                WHERE Results2.Value <= Results.Value) / @Count) >= @Percent
ORDER BY Results.Value ASC

任何建议或帮助将不胜感激。

谢谢!

【问题讨论】:

  • 不,Results.Value 上没有索引。结果是一个表变量。可以为表变量添加索引吗?
  • 看起来你不能,除非你在第一次创建它时声明一个 PRIMARY KEY 或 UNIQUE 约束:sqlserverplanet.com/sql/create-index-on-table-variable - 如果这不是一个选项,也许你应该将 @Results 存储在 @987654324 @ table first,你可以索引。

标签: sql sql-server performance


【解决方案1】:

这将有助于更好地了解要实现的目标,用用户域术语而不是 SQL 来表达。

此外,没有给出被查询数据的整个范围和结构,但可能包括确定性能所涉及的关系。

一方面,有这个结果表变量,它有自己的推导。这种技术可能是有风险的,因为它构建在一个通常是去优化器的隐式临时表中。这就像您试图向查询优化器指示策略。

您似乎只想要一个聚合查询的最大值,它应该是可优化的。实际上,优化甚至不应该成为只有 17K 记录的问题。

您能否以表格形式重申这一点:

SELECT MAX(Value)
FROM some-aggregate-query
GROUP BY fields
HAVING COUNT(something)/COUNT(1) * 100 > @percent

提示:根据我的经验,当您开始分解 SQL 时,您通常会走错方向(这与过程代码的最佳策略完全相反。)

【讨论】:

  • 感谢您的回复。我对您关于表变量是“去优化器”的评论特别感兴趣。你介意详细说明吗?表变量通常不好吗?实际上,我将上面的查询切换为使用临时表,将 TimeStamp 标记为 PK,在 Value 上创建了一个索引,并且执行时间下降到了之前的三分之一以下。什么给了?
【解决方案2】:

嗯,这个怎么样:首先,将总行数选择到一个变量中。接下来,选择索引处的行 (@Percent / 100.0 * countOfRowsTotal),按值排序。

这将扫描表 1 到 2 次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-29
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多