sql-server 内部联接与内部联接(SELECT . FROM)

zzoitvuj  于 2022-10-31  发布在  其他
关注(0)|答案(5)|浏览(141)

同一查询的这两个版本在性能方面是否有差异?

--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语句中只提取查询所需的列。但这似乎没有意义,因为查询性能(据我所知)是基于受影响的行数和最终返回的列列表。
两者的查询计划是相同的,所以我猜两者之间没有任何区别。
我说的对吗?

doinxwow

doinxwow1#

您说得对。您做得完全正确,检查了查询计划,而不是试图猜测优化器。:-)

gj3fmq9x

gj3fmq9x2#

不会有太大的差别,但是当你有一些计算,聚合等需要在版本2之外连接时,版本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
kcrjzv8t

kcrjzv8t3#

看起来是相同的,只是以防SQL服务器不会尝试读取查询不需要的数据,优化器足够聪明
它可以在复杂查询上进行连接时有意义(即,其本身具有连接、分组等),那么,是的,最好指定必填字段。
但还有一点。如果查询很简单,这没有什么区别,但每一个额外的操作,即使是应该提高性能,使优化器的工作更难,优化器可能无法及时获得最佳计划,并将运行非最佳查询。所以额外的选择可能是这样一个操作,甚至可以降低性能

sgtfey8w

sgtfey8w4#

尽管对于较小的数据集来说,这并不重要,但是,更好的方法是使用CROSS APPLY方法而不是连接语句。特别是当服务器被许多查询访问时。代码可以是:

SELECT p.Name, s.OrderQty
FROM Product p
CROSS APPLY (SELECT OrderQty 
FROM   SalesOrderDetail
WHERE  ProductID = p.ProductID ) s
wlzqhblo

wlzqhblo5#

您从查询计划中进行检查是正确的。但是我对版本2有100%的信心。当记录数非常高时,它会更快。
我的数据库大约有1,000,000条记录,而这正是查询计划显示两个查询之间差异的情况。此外,如果您在联接本身中使用where子句,而不是使用where子句,则会使查询更快:
SELECT p.名称,s.订单数量
FROM产品p
INNER JOIN(SELECT产品ID,订单数量FROM销售订单详细信息)p上的s。产品ID = s。产品ID WHERE p有效= 1
此查询的较佳版本为:
SELECT p.名称,s.订单数量
FROM产品p
INNER JOIN(SELECT产品ID,OrderQty FROM SalesOrderDetail)p上的s。产品ID = s。产品ID AND p有效= 1
(假设isactive是product表中的一个字段,表示活动/非活动产品)。

相关问题