【问题标题】:SQL Server - Select * vs Select Column in a Stored ProcedureSQL Server - 在存储过程中选择 * 与选择列
【发布时间】:2013-06-20 13:26:27
【问题描述】:

在临时查询中使用 Select ColumnName 更好,但是在存储过程中保存在计划指南中之后是否重要?

【问题讨论】:

  • 是的! ! 这很重要!我建议总是明确指定您想要的列。否则:如果某人(DBA 或其他开发人员)突然将三个 BLOB 列添加到您的表中会发生什么?您使用SELECT * 的存储过程将获取所有这些列 - 即使您根本不需要它们。请参阅Bad habits to kick: using SELECT * / omit the column list 进行精彩讨论
  • 如果有人愚蠢到将 3 个 BLOB 列添加到任何没有它们也能正常工作的表中,让他们陷入困境......或者让他们使用水平分区(如果你是一个好撒玛利亚人)。
  • @Serge - 什么?每次需要添加新的 BLOB 列时,您都会创建一个新表,以满足可能使用过 * 的人的需求?
  • @Martin 差不多,因为 BLOB 几乎总是意味着您现在访问的“可选额外数据”,然后添加到您经常访问的“关键紧凑行”中。
  • @Serge 期望别人总是做“正确”的事情本身就是错误的。你应该防御性地编码。就像开车一样……您可以通过假设其他人做错事来避免事故。我会使用“select *”来自我自己的临时表、表变量或 CTE。或者,如果我明确需要表中的所有列,即使表发生更改,例如将表行归档为 XML 时。

标签: sql sql-server database tsql stored-procedures


【解决方案1】:

始终显式声明列,即使在存储过程中也是如此。 SELECT * 被认为是不好的做法。

例如,您不知道将返回的列顺序,某些应用程序可能依赖于特定的列顺序。

即应用程序代码可能类似于:

Id = Column[0]; // bad design

如果您使用过SELECT * ID 可能不再是第一列并导致应用程序崩溃。此外,如果修改了数据库并添加了额外的 5 个字段,您将返回可能不相关的其他字段。

【讨论】:

  • 请证明,这总是一个不好的做法。
  • 达伦……我也是。我在一个新地方,看到它选择 * 使用了很多。所以在确定自己没有错过任何事情之前,我就像挠头不想说什么。
  • @user2505334 / 塞尔吉。更新了我的答案以包括原因。
  • @Darren,依赖列顺序是一种不好的做法,首先要避免。但我会告诉你,防止给外部不良做法用户带来麻烦是非常有意义的。 +1
  • 列索引问题的另一个示例:对于长时间运行的项目,可以使用脚本添加表列。有时调试环境和生产数据库中的列顺序可能不匹配。在这种情况下 SELECT * 将以不同的顺序返回列。这可能会破坏 UNION SELECTORDER BY 1,3,5 等声明。
【解决方案2】:

这些主题总是会引发笼统的陈述,例如总是这样做或从不这样做,但现实情况是,就像大多数事情一样,这取决于具体情况。我承认,列出列通常是一种好的做法,但使用 SELECT * 是否是不好的做法取决于具体情况。

考虑所有具有一个或两个公共字段的各种表,例如,我们有许多具有不同布局的表,但它们都有“access_dt”和“host_ip”。这些表格通常不会一起使用,但在某些情况下,可疑活动会提示所有活动的完整报告。这些并不常见,而且需要人工审核,因此,它们由存储过程很好地服务,该存储过程通过循环遍历每个日志表并使用 SELECT * 利用所有表之间的公共字段来生成报告。

在这种情况下列出字段是浪费时间。

再次,我同意列出字段通常是一种好的做法,但使用SELECT * 并不是总是不好的做法。

编辑:试图澄清一下示例。

【讨论】:

  • 您的“跨表分析”示例根本不清楚。 SELECT * 将如何使用?
  • 用于仅基于所有表共有的几个字段输出多个表中的所有字段。
【解决方案3】:

一般来说这是一种最佳做法,但如果您确实需要所有列,则最好使用快速阅读的“SELECT *”。
重要的是要避免检索您不需要的数据。

【讨论】:

    【解决方案4】:

    在使用表扫描查询大型数据集时,在存储过程等情况下,这种做法被认为是不好的做法。您希望避免使用表扫描,因为它会影响查询的性能。这也是可读性的问题。

    【讨论】:

      【解决方案5】:

      其他一些值得思考的食物。如果您的查询有任何连接,那么您将返回不需要的数据,因为连接列中的数据是相同的。此外,如果稍后更改表以添加一些您不需要的东西(例如用于审计目的的列),您可能会向用户返回他们不应该看到的数据。

      【讨论】:

        【解决方案6】:

        没有人提到您需要表中的所有列的情况,即使列发生变化,例如将表行归档为 XML 时。我同意不应该使用“SELECT *”来代替“我需要表中当前存在的所有列”,只是出于懒惰或为了可读性。需要有一个正当的理由。当需要“表中可能存在的所有列”时,这可能是必不可少的。

        另外,如何为表创建“包装”视图?

        【讨论】:

          猜你喜欢
          • 2015-02-21
          • 1970-01-01
          • 1970-01-01
          • 2021-09-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多