66

同一查询的这两个版本在性能方面有什么区别吗?

--Version 1
SELECT p.Name, s.OrderQty
FROM Product p
INNER JOIN SalesOrderDetail s on p.ProductID = s.ProductID

--Version 2
SELECT p.Name, s.OrderQty
FROM Product p
INNER JOIN (SELECT ProductID, OrderQty FROM SalesOrderDetail) s on p.ProductID = s.ProductID

我听说(由 DBA)说版本 2 更快,因为它在内部 SELECT 语句中只获取查询所需的列。但这似乎没有意义,因为查询性能(据我所知)基于受影响的行数和返回的最终列列表。

两者的查询计划是相同的,所以我猜两者之间没有任何区别。

我对么?

4

4 回答 4

49

你是对的。你做了完全正确的事,检查查询计划而不是试图事后猜测优化器。:-)

于 2012-07-20T07:07:53.690 回答
15

不会有太大区别。但是,当您有一些应该在其外部加入的计算、聚合等时,版本 2 会更容易

--Version 2 
SELECT p.Name, s.OrderQty 
FROM Product p 
INNER JOIN 
(SELECT ProductID, SUM(OrderQty) as OrderQty FROM SalesOrderDetail GROUP BY ProductID
HAVING SUM(OrderQty) >1000) s 
on p.ProductID = s.ProdctId 
于 2012-07-20T07:11:27.980 回答
1

似乎是相同的,以防 SQL 服务器不会尝试读取查询不需要的数据,优化器足够聪明

连接复杂查询(即本身具有连接、分组等)时可能有意义,然后,是的,最好指定必填字段。

但还有一点。如果查询很简单,则没有区别,但即使是应该提高性能的每一个额外操作都会使优化器更加努力地工作,并且优化器可能无法及时获得最佳计划,并且不会运行最佳查询。所以 extras select 可能是这样的动作,它甚至会降低性能

于 2012-07-20T07:11:01.617 回答
-3

通过检查查询计划,您做了正确的事情。但我对版本 2 有 100% 的信心。当关闭记录的数量非常高时,它会更快。

我的数据库有大约 1,000,000 条记录,这正是查询计划显示两个查询之间差异的场景。此外,如果您在连接本身中使用它,而不是使用 where 子句,它会使查询更快:
SELECT p.Name, s.OrderQty
FROM Product p
INNER JOIN (SELECT ProductID, OrderQty FROM SalesOrderDetail) s on p.ProductID = s.ProductID WHERE p.isactive = 1

此查询的更好版本是:

SELECT p.Name, s.OrderQty
FROM Product p
INNER JOIN (SELECT ProductID, OrderQty FROM SalesOrderDetail) s on p.ProductID = s.ProductID AND p.isactive = 1

(假设 isactive 是产品表中的一个字段,表示活动/非活动产品)。

于 2012-07-20T09:03:18.623 回答