从表中选择*与从表中选择col1,col2,col3 [重复]
Posted
技术标签:
【中文标题】从表中选择*与从表中选择col1,col2,col3 [重复]【英文标题】:Select * from table vs Select col1,col2,col3 from table [duplicate] 【发布时间】:2013-01-21 17:58:23 【问题描述】:可能重复:select * vs select column
我刚刚和我的一位同事讨论了在存储过程中指定查询命令时的 SQL Server 性能。
所以我想知道哪个比另一个更受欢迎,以及背后的具体原因是什么。
假设,我们确实有一张名为 员工(EmpName,EmpAddress)
我们想从表中选择所有记录。所以我们可以用两种方式编写查询,
从员工中选择 *
从员工中选择 EmpName、EmpAddress
所以我想知道上述查询中是否存在任何特定差异或性能问题,或者它们是否与 SQL Server 引擎相同。
更新:
-
可以说表架构不会再改变了。所以以后的维护没有意义。
性能方面,可以说,使用率非常高,即数据库服务器上每秒数百万次点击。我希望对这两种方法都有一个清晰准确的性能评级。
不对整个表进行索引。
【问题讨论】:
在你alter
table
之前它们是平等的。
您的表上没有索引,您担心 select * 与 select col1,col2 的性能?我认为你需要考虑你的优先事项。
伙计们,只有在没有其他列并且没有更窄的覆盖索引时它们才相等。
让我换一种说法:SELECT * 永远不会比命名列更有效。帮自己一个忙,即使表现相同,也不要偷懒。
@Manish 因为您只需键入一次代码。当你这样做时,你应该验证它的准确性,与消费应用程序建立一个适当的接口(你不能只在 C# 中使用 *,例如,在显示数据时)等等。你不应该依赖这种情况下的性能相似,因为在地球上几乎所有其他情况下都不会出现这种情况(有多少表永远不会改变?有多少表没有索引?)。再一次,您完全专注于效率的错误方面。
【参考方案1】:
如果您在表格中添加一列,具体的差异会显示其丑陋的头部。
突然间,您希望返回两列的查询现在返回三列。如果您专门为这两列编码,那么您的其余代码现在已损坏。
在性能方面,应该没有区别。
在处理数据库时,我始终认为尽可能具体是最好的方法。如果表格有两列,而您只需要这两列,请具体说明。指定这两列。以后会省去你的麻烦。
【讨论】:
考虑 DataRow[1] 在您的代码中,并且有人在您的意思的列之前在 DB 方案中添加了一列...【参考方案2】:我也是“尽可能具体”规则的***拥护者。从长远来看,不遵循它会伤害你。但是,您的问题似乎来自不同的背景,所以让我尝试回答一下。
当您向 SQL Server 提交查询时,它会经历几个阶段:
-
通过网络传输查询字符串。
解析查询字符串,生成解析树
将解析树中的引用对象链接到现有对象
根据统计信息和行数/大小估计进行优化
正在执行
通过网络传输结果数据
让我们来看看每一个:
-
* 查询短了几个字节,所以这一步会更快
* 查询包含较少的“令牌”,因此这应该(!)更快
在链接过程中,需要提取列列表并与查询字符串进行比较。这里“*”被解析为实际的列引用。如果不访问代码,就不可能说哪个版本需要更少的周期,但是访问的数据量大致相同,因此应该是相似的。
-6。在这些阶段,两个示例查询之间没有区别,因为它们都将编译为相同的执行计划。
考虑到所有这些,使用*
表示法可能会节省几纳秒。但是,您的示例非常简单。在更复杂的示例中,在多表连接中指定为表的列子集可能会导致与使用*
不同的计划。如果发生这种情况,我们可以确定显式查询会更快。
上述比较还假设 SQL Server 进程单独运行在单个处理器上,并且没有同时提交其他查询。如果该过程必须在编译期间产生,那么这些额外的周期将远远超过我们试图保存的周期。
因此,与实际执行时间相比,我们所说的节省量非常小,不应成为“糟糕”编码实践的借口。
我希望这能回答您的问题。
【讨论】:
【参考方案3】:您应该始终明确引用列。这样,如果表结构发生更改(并且此类更改是以一种智能的、向后兼容的方式进行的),您的查询将继续工作并且可以随着时间的推移进行修改。
此外,除非您确实需要表中的所有列(不是典型的),否则使用 SELECT * 会为您的应用程序带来比必要更多的数据,并且可能会强制执行聚集索引扫描,而不是可能已经满足更窄的覆盖指数。
Bad habits to kick : using SELECT * / omitting the column list【讨论】:
哦,我理解 select * 的索引和向后兼容性问题,但是如果我们都确保表的整个架构不会发生变化,那么您也会更喜欢明确指定列。 @ManishRawat 是表中仅有的两列吗?如果你关心的是性能,为什么你对索引死心塌地? (提示:它们对您的大多数查询的影响要比您对 select * 的选择结果大得多。 我从上下文中删除了索引,以确保没有人说索引更注重性能,如果您指定索引列,那么它的性能再次提升。【参考方案4】:在性能方面,我认为这两个之间没有区别。但是这两个在不同的情况下使用,可能有什么区别。 考虑一个稍微大一点的表。如果您的表(Employees)包含 10 列,那么第一次查询将保留该表的所有信息。但是对于第二次查询,您可以指定您需要哪些列信息。所以当您需要所有最好是一号员工的信息,而不是指定所有的列名。 当然,当你需要 ALTER 一个表时,那 2 个就不相等了。
【讨论】:
但是@ridoy 我在某处读到 Select * 在运行时转换为 Select col1,col2 并且使用 Select * 也会对性能造成影响。对吗? 这种性能影响是如此微不足道,以至于不值得花精力去谈论它。这里提到的其他影响非常非常重要。 我也同意亚伦的观点。 @AaronBertrand ,所以即使是地球上每个人的一分钱也可以让你成为百万富翁。因此,您在查询中节省的每一纳秒都会给您带来巨大的性能提升。因此,根据我的理解,如果我在答案中添加/删除一些有效点,那么我将确切地知道这两个查询在哪一部分不同。有关更新:请参阅问题,因为我对问题进行了一些更改。 @Manish 我的观点仍然成立:从性能的角度来看,SELECT * 永远不会更有效率(可能只节省了几秒钟的打字时间)。那么为什么要使用它,即使只获得与 SELECT col1, col2 一样的 相同 性能,您也只能在那些非常特定的情况下这样做 - 其中那些是 ALL 中的列表(或没有覆盖索引),当您确实需要 ALL 表中的列时。您是否试图找到 SELECT * 更有效的证据?为什么,你要花多长时间去寻找它? (提示:你不会。)以上是关于从表中选择*与从表中选择col1,col2,col3 [重复]的主要内容,如果未能解决你的问题,请参考以下文章