可以选择*用法是否合理?

Sco*_*ttE 62 sql select

我一直向我的开发者讲道,这SELECT *是邪恶的,应该像瘟疫一样避免.

有什么理由可以说是合理的吗?

我不是在谈论COUNT(*)- 大多数优化者都可以解决这个问题.

编辑

我在谈论生产代码.

我看到这个不好的做法的一个很好的例子是select *在存储过程中使用的传统asp应用程序,用于ADO循环返回的记录,但是通过索引得到列.您可以想象在字段列表末尾之外的某处添加新字段时发生的情况.

Mar*_*ith 45

我很高兴*在审计触发器中使用.

在这种情况下,它实际上可以证明是有益的,因为它将确保如果将额外的列添加到基表中,它将引发错误,因此不能忘记在审计触发器和/或审计表结构中处理此问题.

(像dotjoe一样)我也很高兴在派生表和列表表达式中使用它.虽然我习惯性地反过来做.

WITH t
     AS (SELECT *,
                ROW_NUMBER() OVER (ORDER BY a) AS RN
         FROM   foo)
SELECT a,
       b,
       c,
       RN
FROM   t; 
Run Code Online (Sandbox Code Playgroud)

我最熟悉SQL Server,至少优化器可以识别只a,b,c需要列*,并且在内表表达式中的使用不会导致任何不必要的开销检索和丢弃不需要的列.

原则上SELECT *应该在视图中应该是正常的,并且SELECT它应该是应该避免的视图中的最终,但是在SQL Server中这会导致问题,因为它存储视图的列元数据,当基础表更改时不会自动更新*除非sp_refreshview运行更新此元数据,否则使用会导致混淆和不正确的结果.

  • +1,当不使用触发器但使用OUTPUT子句时也将数据发送到审计表 (3认同)

Dyl*_*tie 34

在许多情况下,SELECT*是最佳解决方案.在Management Studio中运行即席查询只是为了了解您正在使用的数据.查询您不知道列名的表,因为这是您第一次使用新架构.构建一次性quick'n'dirty工具来进行一次性迁移或数据导出.

我同意在"正确"开发中,你应该避免它 - 但是有很多场景,"正确"开发不一定是业务问题的最佳解决方案.规则和最佳实践是很好的,只要你知道什么时候打破它们.:)

  • "规则和最佳实践都很棒,只要你知道什么时候打破它们"+1,我总是被告知"这已经足够了". (12认同)
  • 不幸的是,根据我的经验,这不是人们使用select*的原因 - 他们因为懒惰而使用它. (3认同)

dot*_*joe 28

在与CTE合作时,我会在生产中使用它.但是,在这种情况下,它并不是真的select *,因为我已经在CTE中指定了列.我只是不想在最终选择中重新指定.

with t as (
    select a, b, c from foo
)

select t.* from t;
Run Code Online (Sandbox Code Playgroud)

  • DRY方法的一个很好的例子.不要重复自己. (3认同)

Ode*_*ded 25

如果你在谈论实时代码,我无法想到.

人们说它使得添加列更容易开发(因此它们自动返回并且可以在不更改存储过程的情况下使用)不知道编写最佳代码/ sql.

我只在编写不会被重用的即席查询时使用它(找出表的结构,当我不确定列名是什么时获取一些数据).


Jor*_*dão 16

我认为select *在一个exists条款中使用是合适的:

select some_field from some_table 
where exists 
 (select * from related_table [join condition...])
Run Code Online (Sandbox Code Playgroud)

有些人喜欢select 1在这种情况下使用,但它并不优雅,并且它不会购买任何性能改进(早期优化再次打击).

  • @dotjoe:"选择1"的问题在于人们认为他们正在创造智能优化(我曾多次听到).他们不是.至于概念差异,exists子句用于检查_any_行是否存在,而不仅仅是1,所以我认为*最好描述_any_而不是1. (8认同)
  • `select 1`是早期优化而不是优雅?世界卫生大会?大声笑,这是1个字符或另一个字符之间的区别.几乎不需要任何努力.实际上,`select 1`可能会更好地理解exists子句.它只关心行. (4认同)
  • 我的问题是"我是一个聪明的优化器"问题.有些人甚至使用`select top 1 1`(在SQL-Server中).至于概念问题,我认为我们不能达成协议.为了真正结束辩论,我们应该能够在一个存在子句中做的是完全省略列:`select from table`,或者有另一种语法说"我不关心":`select _ from table`(借用一些函数式语言).当语言没有提供表达_exactly_我​​们想要的工具时,概念差异都可以解释. (3认同)
  • 确定的答案:它*是可以接受的.其他任何事情都是无知/迷信.ANSI标准提到未解析EXIST中的列列表.第191页,http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt.这导致了这个片段:... EXISTS(SELECT 1/0 FROM ...请在此处查看示例:http://stackoverflow.com/questions/2019958/ (3认同)
  • 这有点像计数(*),但好点,+ 1 (2认同)

Ale*_*rey 7

在生产代码中,我倾向于100%同意你.

但是,我认为在执行即席查询时,*不仅仅证明了它的存在.


sha*_*nus 6

你已经对你的问题得到了很多答案,但你似乎正在解雇一切并非扼杀你想要听到的东西.不过,这里是第三(到目前为止)时间:有时没有瓶颈.有时表现比罚款要好.有时表格不断变化,修改每个SELECT查询只是管理可能不一致的一点.有时你必须按照不可能的时间表交付,这是你需要考虑的最后一件事.

如果您住在子弹时间,请确保输入所有列名称.但为何停在那里?在无架构的dbms中重写您的应用程序.地狱,在汇编中编写自己的 dbms.这真的显示了他们.