1

我遇到了一个存储过程,它有一些错误。一个是,开发人员这样做了:

SELECT alias.firstname, alias.surname, alias.id
FROM
    (SELECT firstname, surname, id, address, anotherfield, etc, etc
     FROM TableName
     WHERE afield = avalue) alias

因此,这显然与以下内容相同:

SELECT firstname, surname, id
     FROM TableName
     WHERE afield = avalue

这被重复了很多次。所以,我的问题是,执行子查询是否会降低性能?我知道这是没用的……最好的办法就是把它改正——我做到了。但是,离开它是否有任何性能损失?

我猜查询优化器会理解它,并且做正确的事情?

4

3 回答 3

2

在外部查询中只涉及投影的情况下,两个查询之间的执行计划应该绝对没有差异。在内部和外部查询中使用“where”子句的更复杂的查询可能会测试查询优化器的限制,并且可能会为两级查询生成较差的查询计划,但在您的情况下,计划和执行速度应该是完全相同的。

于 2013-03-06T00:45:12.423 回答
2

在像这样的简单情况下,SQL Server 会将这些查询折叠到同一个执行计划中。

我在 AdventureWorks2012 上试过这个:

SELECT CarrierTrackingNumber, ProductID, UnitPrice, LineTotal
FROM 
(
  SELECT *
    FROM Sales.SalesOrderDetail
    WHERE ProductID = 781
) AS Alias;

SELECT CarrierTrackingNumber, ProductID, UnitPrice, LineTotal
FROM Sales.SalesOrderDetail
     WHERE ProductID = 781;

这些计划是相同的,运行时指标的差异是无法区分的。

在此处输入图像描述

我还尝试了以下方法,特意选择了一个复杂类型(地理)的表:

 SELECT AddressLine1, City, StateProvinceID 
 FROM Person.Address
   WHERE StateProvinceID = 9;

 SELECT AddressLine1, City, StateProvinceID 
 FROM 
 (
   SELECT * FROM Person.Address
   WHERE StateProvinceID = 9
 ) AS x;

 SELECT AddressLine1, City, StateProvinceID 
 FROM 
 (
   SELECT * FROM Person.Address
 ) AS x
 WHERE StateProvinceID = 9;

同样的事情,在每种情况下,优化器都会崩溃到索引扫描并忽略似乎被引用的其他列:

在此处输入图像描述

您是否可以依靠这种相同的优化来处理更复杂的查询,我不确定。优化器并不总是完美或可预测的......所以我当然可以设想更多涉及的查询,其中这种崩溃不会可靠地发生。

我不确定我是否理解您所看到的模式的价值。也许那里有一些例子实际上可以达到某种目的。

于 2013-03-06T00:58:53.733 回答
1

两个查询的执行计划在性能方面是相同的。优化器只会丢弃未使用的列。

于 2013-03-06T00:38:34.480 回答