我使用 SQL Server 2012
并编写此查询:
DBCC DROPCLEANBUFFERS;
SET STATISTICS IO ON;
我在上面写了两行清洁现金并设置统计数据 .
这些是我的疑问:
SELECT C.custid, C.companyname, O.orderid, O.orderdate
FROM Sales.Customers AS C
INNER JOIN Sales.Orders AS O
ON C.custid = O.custid
SELECT C.custid, C.companyname, O.orderid, O.orderdate
FROM Sales.Customers AS C
INNER JOIN Sales.Orders AS O
ON C.custid = O.custid
WHERE O.custid < 5
但我得到了这个统计数据:
对于第一个查询:( 830行受影响)表'工作表' . 扫描计数0,逻辑读取0,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'订单' . 扫描计数1,逻辑读取21,物理读取1,预读读取25,lob逻辑读取0,lob物理读取0,lob预读读取0.表'客户' . 扫描计数1,逻辑读取2,物理读取1,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0 .
对于第二个查询:(30行受影响)表'客户' . 扫描计数0,逻辑读取60,物理读取1,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'订单' . 扫描计数1,逻辑读取21,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0 .
为什么 logical reads
在第二个查询中考虑行数多于第一个?
2 回答
没有条件:
条件:
区别在于第一种情况下的扫描(由于表格很小,速度很快)与通过索引重复的随机访问(不是那么快,因为表太小而无法理解) .
但请注意,由嵌套循环连接引起的所有这些重复逻辑读取都不会导致实际的I / O(物理读取),因为它们会一遍又一遍地转到相同的几个块(并且这些块在您的缓冲区缓存中工作组) .
这会对您造成性能问题吗?似乎查询足够快 . 希望优化器能够适用于真正重要的情况(即涉及大表的情况) .
也许对于First查询,可以使用索引,而不是第二个查询 . custid可能只是一个INCLUDED列,而不是索引中的键列 . 您可以在执行计划中看到这一点 .