我听说在编写SQL命令时使用SELECT *通常是不好的做法,因为选择您特别需要的列会更有效。

如果我需要选择表中的每一列,我应该使用

SELECT * FROM TABLE

or

SELECT column1, colum2, column3, etc. FROM TABLE

在这种情况下,效率真的重要吗?如果你真的需要所有的数据,我认为SELECT *在内部会更优,但我这么说并没有真正理解数据库。

我很好奇在这种情况下最好的做法是什么。

更新:我可能应该指定,我真正想要执行SELECT *的唯一情况是,当我从一个表中选择数据时,我知道总是需要检索所有列,即使添加了新列。

然而,鉴于我所看到的反应,这似乎仍然是一个坏主意,由于我曾经考虑过的许多技术原因,SELECT *不应该被使用。


当前回答

到目前为止,这里回答了很多很好的理由,这里还有一个没有被提到的理由。

显式地命名列将帮助您进行后续的维护。在某些情况下,您将进行更改或排除故障,并发现自己在问“这个列到底用在哪里”。

如果显式列出了名称,那么通过所有存储过程、视图等查找对该列的每个引用就很简单了。只需为您的DB模式转储一个CREATE脚本,并在其中进行文本搜索。

其他回答

我总是建议指定您需要的列,以防您的模式发生变化而不需要额外的列。

此外,用表名限定列名。当查询包含连接时,这很重要。如果没有表限定,就很难记住哪个列来自哪个表,并且向其他表之一添加类似名称的列可能会破坏查询。

在执行效率方面,我不知道有什么显著差异。但是为了程序员的效率,我会写字段名,因为

如果您需要按数字进行索引,或者您的驱动程序对blob-values的行为很奇怪,那么您需要一个明确的顺序 如果需要添加更多字段,则只读取所需的字段 如果拼写错误或重命名字段,而不是记录集/行中的空值,则会得到sql-error 你可以更好地了解发生了什么。

同时也要记住变化。今天,Select *只选择您需要的列,但明天它可能还会选择我刚刚添加的varbinary(MAX)列,而您现在还可以检索所有3.18 gb的二进制数据,这些数据昨天不在表中。

您实际上应该只选择您需要的字段,并且只选择所需的数量,即。

SELECT Field1, Field2 FROM SomeTable WHERE --(constraints)

在数据库之外,动态查询有注入攻击和畸形数据的风险。通常使用存储过程或参数化查询来解决这个问题。而且(虽然不是真正的大问题)服务器必须在每次执行动态查询时生成一个执行计划。

如果记录要遍历internet,那么限制返回的列可以大大提高性能。