【问题标题】:Should all sub queries be replaced with temporary tables?是否应该用临时表替换所有子查询?
【发布时间】:2023-03-15 14:15:01
【问题描述】:

我一直在研究一个解决方案(在 SQL Server 中),其中所有子查询无一例外都被临时表重写以提高性能。

举个例子,所有的查询都是这样的:

SELECT something 
FROM (SELECT * FROM T1 WHERE condition1) 
JOIN ...

已经改写成这样:

SELECT * 
INTO #tempTable 
FROM T1 
WHERE condition1

SELECT something 
FROM #tempTable  
JOIN ...

还建议here 应避免所有子查询以支持临时表。

基于给定的事实,所有子查询都应该替换为临时表吗?如果不是,什么时候应该考虑一个而不是另一个?

【问题讨论】:

  • sql server 中唯一没有例外的绝对规则是“它取决于”。我会非常强烈地争辩说,只是盲目地将每个子查询都放入临时表中是徒劳和沮丧的。在某些情况下,它可能会提高性能,但在其他情况下,它可能会使情况变得更糟。考虑一个有一百万行的子查询。虽然这可能不是编写将大量数据复制到临时表的代码的好方法,但速度会更慢。充其量你可能正在“修复”一个甚至不存在的性能问题。
  • 这几乎就是您正在寻找的答案:stackoverflow.com/a/11169910/2333499

标签: sql sql-server query-performance


【解决方案1】:

这太荒谬了。开个玩笑。

您的“子查询”可以正常使用。 SQL Server 只是忽略它。您可以将其重写为:

SELECT something
FROM T1 JOIN . . .
WHERE condition1

SQL Server 应该对此进行正确优化。

根据我使用 SQL Server 的经验,很少有需要创建临时表来优化查询的情况。更常见的是,我使用查询提示来避免嵌套循环连接。

如果需要一个临时表,那么表上几乎总是会有索引。这是使用临时表的关键原因之一。 (另外两个是因为同一个查询块通过一个查询或多个查询重复)。

【讨论】:

  • @SqlZim 还提供了一个很好的链接-“临时表是另一回事,因为您提供了有关如何运行查询的更多指导。一个主要区别是优化器可以使用统计信息从临时表中建立其查询计划。这可能会导致性能提升”。答案是... mmm ...
  • @scsimon - 因此“答案是由 ... mmm ... 给出的”:-)
  • 这是 OP 在他们的问题中发布的链接的第二个答案中的第二个链接。他可能值得一票,因为他引用了一个好的来源:stackoverflow.com/a/16768252/2333499
【解决方案2】:

在关于子查询的讨论中我不常看到的一点是人为因素,特别是嵌套对象的可读性代码的可维护性。 p>

与其他形式的人工阅读代码一样,运行和编辑查询的人员能够了解他们正在运行的内容以及查询的不同部分如何相互交互,这一点很重要。除了仅检索和传递少数元素的简单子查询之外,越来越复杂的子查询可能会变得更难以阅读和理解查询(以及它与超级查询的关系),并且由于其他原因可能更难以维护,而不是花时间理解查询(例如如果嵌套涉及大量代码重复)。

更重要的是,最初的简单子查询可能会扩展为更复杂,此时您可能必须将子查询提取到临时表中以使其可读/处理真正的性能问题(那种戈登林诺夫提到)。根据团队成员对这种重构的舒适程度以及对使用子查询的脚本的任何依赖(例如使用存储过程),这种不得不为重构增加时间的可能性可能意味着经理会将临时表作为 样式引入偏好 与“性能提升”一样多。

【讨论】:

    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 2011-08-24
    • 2013-02-07
    • 1970-01-01
    • 2018-08-03
    相关资源
    最近更新 更多