【问题标题】:Pointless Use of Temporary Tables?无意义地使用临时表?
【发布时间】:2013-08-31 16:07:39
【问题描述】:

我正在修复大约一年前设计的相当复杂的 SSRS 报告中的缺陷。据我所知,编写报告的人——我们组织的一名承包商,现在已经离开,无法回答问题——几年前学习了 SQL,但没有跟上它的最新状态——他的代码充满了过时和不好的做法,例如加入 WHERE 子句,按列号而不是列名排序,以及始终使用临时表而不是子查询或 CTE。作为 SQL 的新手(不到一年的经验),我总是试图弄清楚我遇到的一些奇怪编码的目的,并了解它使用的任何过时技术的历史。这是我无法弄清楚的一个 - 我目前正在使用的报告的存储过程在使用数据之前将所有内容选择到临时表中。如果编码人员需要三列、50 行查找表中的两列,他会首先将这两列选择到临时表中。即使对于最终的 SELECT,他总是先选择一个临时表,然后执行 SELECT * 来访问数据。我以前没见过这个,对我来说似乎毫无意义。为什么不直接访问数据?在 SQL 的历史中,是否存在或曾经存在这样做的任何目的,或者只是简单的糟糕编码?

【问题讨论】:

  • 谢谢,戈登和普拉哈拉德。我没有考虑你建议的原因。我认为编码员对如何编码有某种误解。从他的其他一些代码来看,我想知道他在编写这份报告之前是否已经离开 SQL 一段时间了。我会投票支持你的两个答案,但我没有这样做所需的最低分数。

标签: sql tsql reporting-services temp-tables


【解决方案1】:

我会猜测一下-使用临时表的原因。请注意,下面提到的推理只是一些观点,不一定是真正的原因。可能只是个人不知道编写 SQL 的正确方法。但是,这里有一些使用临时表的原因:

  1. 模拟视图 - 例如他在 50 行表的 3 列中只选择了 2 列,这意味着他实际上只想要这两列中数据的逻辑视图 - 这可以使用 CTE 轻松完成。
  2. 隔离数据更改 - 他想确保他始终在处理数据的副本,以便与基表的数据更改隔离(本质上,这变成了主表)并且也不想让他的查询对基表进行意外修改。
  3. 性能 - 可能是他要查询的原始表的搜索和排序索引构建不佳 - 他碰巧通过构建临时表来弥补这一点,该索引构建在查询中所需的列上,这将帮助他实现更快的查询处理。它还将为他提供一种方法来防止对主表结构进行任何更改(这会减慢插入和删除等其他操作)。

话虽如此,重要的是要注意这些都是不好的编码习惯。始终建议使用 SQL Server 提供的 CTE、Views 等工具来处理数据库中的数据。当您想在插入表之前对数据进行预处理时,临时表是一个不错的选择,并且在数据库之外这样做会很昂贵(例如,想象一个从转储文件中读取数据并将它们插入到主表包含数百万行。可能是转储表包含重复数据,这些数据已经在表中持久化,因此我们不想插入这样的行。在这种情况下,数据处理系统可以转储候选行进入一个临时表,然后使用 SQL Server 强大的集合操作来过滤掉重复的行。)

【讨论】:

    【解决方案2】:

    根据你的描述,我认为这是糟糕的编码。

    在某些情况下,我可以想象按照您的描述进行选择。大多数属于“表需要很长时间才能读取”或“优化器无法有效使用表中的统计信息”的类别。一个原因可能是该表位于不同服务器上的数据库中。拥有本地副本通常会使查询大大更有效率。或者,“表格”实际上可能是一个需要很长时间才能处理的视图。

    另一种情况是,当表格上有大量更新时,您出于某种原因需要快照以获取一系列报告。您可能需要不同报告之间的一致性,因此将数据放入临时表可以保证这一点。

    不过,一般来说,您永远不会这样做。如果您有一个小型参考表,您只需将其包含在from 子句中并访问您需要的列。 SQL Server 在优化对表的访问和将处理仅限于需要的列方面做得很好。将东西放在临时表中会阻碍优化器——这通常(但不总是)是一件坏事。

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 2016-01-15
      • 2015-01-13
      • 1970-01-01
      • 2011-01-26
      • 1970-01-01
      • 2013-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多