'SELECT *' 子查询效率低下吗?

DAR*_*EAN 0 performance sql-server optimization t-sql query-performance

我们有一个第三方分析平台,允许最终用户从选择的预定义视图中创建自己的表格和图表。这将查询 MS SQL 数据库。

不幸的是,根据我的知识和理解,该软件注入数据库以查询数据的 SQL 语法似乎非常低效,或者看起来如此。

例如,以下是将两个表连接在一起的查询的样子:

SELECT tblOne.ColumnOne, tblOne.ColumnTwo, tblTwo.ColumnThree
FROM (SELECT * FROM tblOne) AS tblOne
JOIN (SELECT * FROM tblTwo) AS tblTwo ON tblOne.id = tblTwo.id
Run Code Online (Sandbox Code Playgroud)

现在想象这些表每个都有很多列,或者有更多连接到附加表,每个表都遵循相同的模式 - 我假设这将在子查询中执行全表扫描,有效地读取比实际需要的更多的数据是否正确?我是否也正确地假设以下内容实际上会更有效?

SELECT tblOne.ColumnOne, tblOne.ColumnTwo, tblTwo.ColumnThree
FROM tblOne
JOIN tblTwo ON tblOne.id = tblTwo.id
Run Code Online (Sandbox Code Playgroud)

在我给这个分析解决方案的开发人员写一封措辞强硬的电子邮件之前,我只是想要第二个意见,以防万一我误解了引擎将如何处理这样的查询。

提前致谢。

Dav*_*oft 5

我是否正确假设这将在子查询中执行全表扫描,有效地读取比实际需要的更多?

不。查询优化器应该看透这一点。没有在查询执行中具体化子查询的一般规则。

我是否也正确地假设以下内容实际上会更有效?

可能有足够多的连接和子查询,您可能会得到一个糟糕的计划。但这不是第一个看的地方。使用查询存储 (SQL 2016+)、计划缓存 DMV 或 XEvents 查看查询计划和相关资源成本。

例如在 AdventureWorksDW 上,这两个查询使用相同的计划。

select p.Color, sum(f.SalesAmount) SalesAmount
from
 (select * from FactInternetSales) f
join
 (select * from DimProduct) p
 on p.ProductKey = f.ProductKey
 group by p.Color

 go

select p.Color, sum(f.SalesAmount) SalesAmount
from FactInternetSales f
join DimProduct p
 on p.ProductKey = f.ProductKey
group by p.Color
Run Code Online (Sandbox Code Playgroud)