Sql server 从构建执行计划的角度来看,“选择*”有什么影响?

Sql server 从构建执行计划的角度来看,“选择*”有什么影响?,sql-server,tsql,Sql Server,Tsql,我听说使用“select*”会增加SQL Server构建查询执行计划所需的时间,因为它必须找出引用表上存在哪些列。这同样适用于基于视图而不是表的查询吗?是;列发现过程仍然必须进行。决不能在生产应用程序或流程中使用select*。您应该始终明确定义要检索的特定数据。我敢打赌,无论哪种情况,时间都是可以协商的;但是,由于其他原因,您应该避免选择* 使用select*可以返回比实际需要更多的数据,这取决于数据的重要性。如果删除一个列,那么查询可能仍然有效;但是,消费代码可能会失败。您确实失去了确定是

我听说使用“select*”会增加SQL Server构建查询执行计划所需的时间,因为它必须找出引用表上存在哪些列。这同样适用于基于视图而不是表的查询吗?

是;列发现过程仍然必须进行。决不能在生产应用程序或流程中使用select*。您应该始终明确定义要检索的特定数据。

我敢打赌,无论哪种情况,时间都是可以协商的;但是,由于其他原因,您应该避免选择*


使用select*可以返回比实际需要更多的数据,这取决于数据的重要性。如果删除一个列,那么查询可能仍然有效;但是,消费代码可能会失败。您确实失去了确定是否有人在使用该列的能力。

时间可以忽略不计。是,如果应用于表,则应用于视图

但在使用SQL的12年中,我还没有看到通过显式命名列而不是使用*来加快查询速度

在生产代码中,我不使用*,但这是为了让代码言简意赅,而不是为了效率,因为绑定到结果集时顺序可能很重要

在production视图中,我将使用*if,如果我想说的是将所有列引入视图的目的;这样,重新编译视图将获得表更改。从某种角度看,秩序并不重要;仅在可能使用视图的客户端查询中

编辑时:请注意,视图定义只解析一次,直到重新编译为止,在创建视图时,而不是在使用视图时。因此,从*到第1列、第2列、第3列、第foobar的少量时间只会在创建视图发送到db服务器时发生一次


现在,将所有列返回到客户端将比只返回一列慢,尽管通常不会太多。但这是一个不同的问题。

在查询计划方面没有区别,但是显式定义列被认为是良好的做法,原因有很多,包括:

向表中添加列不会破坏依赖于旧列设置的旧代码。 从不需要的列中选择数据意味着更多的数据传输,这通常是从数据库获取数据最慢的部分。
假设您有一张这样的桌子:

CREATE TABLE t_test (id INT NOT NULL PRIMARY KEY, value1 INT, value2 INT, aux_value VARCHAR(200))
CREATE INDEX ix_test_values ON (value1, value2)
然后您要选择特定范围内的所有值:

SELECT  value1, value2
FROM    t_test
WHERE   value1 BETWEEN 10 AND 20
在这种情况下,SQL Server将只扫描索引ix_test_值。你想知道的一切都包含在这个索引中,这就是为什么除了索引扫描什么都不需要的原因

现在你发布:

SELECT  *
FROM    t_test
WHERE   value1 BETWEEN 10 AND 20
SQL Server现在需要选择id和aux_值以及value1和value2。这些值不包含在索引中,这就是为什么对于每个索引叶,SQL Server应该查看表本身并从表页检索值的原因

这可能比简单的索引扫描花费4到10倍的时间,这取决于表结构的复杂程度以及内存中的页面数量

我听说使用“选择*”会增加 到SQL Server构建所需的时间 查询执行计划,因为它必须 找出上存在哪些列 引用的表

想想看。当您发送以下内容时,SQL Server会做什么:

SELECT ID, col1, col2, col3
  FROM table
上面的语句意味着它不会检查表中是否存在ID、col1、col2等,它会相信你的话吗?天哪,不D

它将在系统目录中查找这些列是否存在。从内部来看,这与说:

SELECT * FROM table
有很多理由不使用SELECT*到目前为止,他们已经在这个列表中列举了,但是声称它为查询解析时间增加了可测量的、有意义的开销是完全愚蠢的。因此,如果有人试图告诉你,请纠正他们: