我有一个快速的表现问题。我有一个select语句如下。 如果所有表都被索引并且相当大(每个表中有超过百万条记录),哪一个会更快。
SELECT A.col1, B.col2, C.col3, D.col4
FROM tableA A WITH (NOLOCK)
INNER JOIN tableB B WITH (NOLOCK) ON A.col1 = B.col1
INNER JOIN tableC WITH (NOLOCK) ON B.col2 = C.col2
INNER JOIN tableD WITH (NOLOCK) ON C.col3 = D.col3
INNER JOIN tableE WITH (NOLOCK) ON D.col4 = E.col4
INNER JOIN tableF WITH (NOLOCK) ON E.col5 = F.col5
INNER JOIN tableG WITH (NOLOCK) ON F.col6 = G.col6
WHERE A.col1 = 95
AND B.col2 = 96
AND C.col3 = 97
AND G.col4 = 98
OR
SELECT A.col1, B.col2, C.col3, D.col4
FROM tableA A WITH (NOLOCK)
INNER JOIN tableB B WITH (NOLOCK) ON A.col1 = B.col1 AND A.col1 = 95 AND B.col2 = 96
INNER JOIN tableC WITH (NOLOCK) ON B.col2 = C.col2 AND C.col3 = 97
INNER JOIN tableD WITH (NOLOCK) ON C.col3 = D.col3
INNER JOIN tableE WITH (NOLOCK) ON D.col4 = E.col4
INNER JOIN tableF WITH (NOLOCK) ON E.col5 = F.col5
INNER JOIN tableG WITH (NOLOCK) ON F.col6 = G.col6 AND G.col4 = 98
答案 0 :(得分:3)
您编写的查询与sql server中实际执行的查询非常不同,sql server optimiser互操作它认为最佳性能的查询。
在给定的场景中,sql server optimiser足够聪明,可以看到两个查询基本相同,并且会提出相同的执行计划。
因此我认为两个查询的查询性能都是一样的。
另一方面,因为您已经为查询中的每个表使用了表提示WITH (NOLOCK)
,所以它相当于将事务隔离级别设置为未提交读取,您可以通过删除所有这些表提示只是在执行查询之前将事务隔离级别更改为未提交读取......
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO
<Your query here>
GO
我在AdventureWorks2012中写了两个不同的查询,一个在WHERE
子句中有过滤条件,另一个在ON
子句中有过滤条件。
SELECT
s.SalesOrderID,
s.CustomerID,
p.FirstName
FROM Sales.SalesOrderHeader AS s
INNER JOIN Sales.Customer AS c ON s.CustomerID = c.CustomerID
INNER JOIN Person.Person AS p ON c.PersonID = p.BusinessEntityID
WHERE C.CustomerID = 29825
AND p.FirstName = 'James'
GO
SELECT
s.SalesOrderID,
s.CustomerID,
p.FirstName
FROM Sales.SalesOrderHeader AS s
INNER JOIN Sales.Customer AS c ON s.CustomerID = c.CustomerID
AND C.CustomerID = 29825
INNER JOIN Person.Person AS p ON c.PersonID = p.BusinessEntityID
AND p.FirstName = 'James'
GO
现在,如果您查看两个查询的执行计划,它们是相同的。