sql-server - 在子查询中使用 select * 会产生糟糕的性能吗?
问题描述
我知道select *
在主查询中使用不好的原因。但是在子查询中会发生什么?
是否从表中检索到所有列,然后仅选择外部选择子句中列出的列?
查询是否已优化,并且仅从表中检索到之后要选择的列?
真实查询示例:
SELECT T1.clave,
T1.titulo,
T1.revision,
T1.fecharevision,
T1.revisadopor,
T1. aprobadopor,
T1.nombrearchivo,
T1.descripcionarchivo,
T1.claverelacionada,
T1.archivo,
T1.link,
T1.fecharevlast,
T1.estatus
FROM (SELECT *,
Row_number()
OVER(
partition BY revision
ORDER BY fecharevlast DESC ) AS orden
FROM motoresemis) AS T1
WHERE T1.clave = 'CMD-01' AND T1.orden = 1
解决方案
对于简单的示例,它不会产生影响 - SQL Server 是一种“声明性”语言,这意味着 SQL 命令指示您想要什么,而不是如何去做。
例如,我有一个名为 Test10k 的简单表,它有 10,000 行,ID 为 PK 整数,然后 Col2、Col3、Col4、Col5 为填充有 GUID 的 varchar(100)。Col2 上有一个非聚集索引。
以下命令都使用相同的计划、基数估计和 IO 统计信息执行完全相同的操作
SELECT ID, rn
FROM (SELECT ID, ROW_NUMBER() OVER (ORDER BY Col2) AS rn
FROM Test10k
WHERE Col2 LIKE 'F%'
) A;
SELECT ID, rn
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY Col2) AS rn
FROM Test10k
WHERE Col2 LIKE 'F%'
) A;
SELECT ID, rn
FROM (SELECT ID, Col3, ROW_NUMBER() OVER (ORDER BY Col2) AS rn
FROM Test10k
WHERE Col2 LIKE 'F%'
) A;
- 前两个使用所需的特定值与 * 比较子查询。
- 第三个显式使用不在非聚集索引中的另一列 (Col3);SQL Server 确定不需要它,因此无论如何都从非聚集索引中获取数据。
SELECT * 最大的问题是在复杂的设置中(尤其是分组等),即使在逻辑上可以使用索引,它也可能不使用索引,因为您的命令足够复杂,SQL Server 会按照您所说的那样处理这些部分。
此外,当您在子查询中获取几乎整个表时, SELECT * 或 SELECT table.* 通常会更好,因为它更容易阅读(如上面的示例)。如果无论如何您都在使用几乎所有字段,那么无论如何都需要使用聚集索引来获取数据。
所以,我的建议
- 尝试使用显式列表,以防万一
- 但是,当给定表中的列列表变得太长/多于少数列时,可以使用 SELECT * (但请考虑,如果连接表,请使用 SELECT 表。*)
推荐阅读
- java - Apache Axis 找不到 WSDL2Java 类
- vb.net - 如果类中的目标已初始化,newtonsoft json 将有效日期时间反序列化为可为空的 datetimeoffset 不同的行为
- javascript - 如何将事件侦听器添加到模板字符串
- javascript - JSF 页面支持 bean 荒谬的延迟
- reactjs - React电话号码输入导致cypress上的webpack错误
- php - 如何改进正则表达式?
- reactjs - React - 不能用作 JSX 组件。它的返回类型 'void' 不是有效的 JSX 元素
- c++ - 文件for循环不打开文件c ++
- java - 如何在java awt中刷新框架的所有内容
- c# - 检查目录是否存在,如果不存在,则显示一个消息框,说明它不存在