Sql server 当我的查询有Where时,为什么SQL Server有更多的I/O?
我使用SQL Server 2012,并编写以下查询:Sql server 当我的查询有Where时,为什么SQL Server有更多的I/O?,sql-server,sql-server-2012,query-optimization,Sql Server,Sql Server 2012,Query Optimization,我使用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
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
选择C.custid、C.companyname、O.orderid、O.orderdate
来自销售。客户为C
内部连接销售。订单为O
在C.custid=O.custid上
选择C.custid、C.companyname、O.orderid、O.orderdate
来自销售。客户为C
内部连接销售。订单为O
在C.custid=O.custid上
其中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
考虑到行的数量,为什么第二次查询中的逻辑读取
多于第一次
对于第一个查询,可能可以使用索引,而对于第二个查询,可能不使用索引。 custid可以只是索引中包含的列,而不是键列。
您可以在执行计划中看到这一点。对于第一个查询,可以使用索引,而对于第二个查询,则不能使用索引。 custid可以只是索引中包含的列,而不是键列。
您可以在执行计划中看到这一点。无条件:
Table 'Customers'. Scan count 1, logical reads 2
条件是:
Table 'Customers'. Scan count 0, logical reads 60,
区别在于第一种情况下的扫描(速度很快,因为表很小)与通过索引进行的重复随机访问(速度不是很快,因为表太小,没有意义)
但请注意,所有这些由嵌套循环联接引起的重复逻辑读取不会导致实际的I/O(物理读取),因为它们会一次又一次地访问相同的几个块(这些块在缓冲区缓存工作集中)
这是否会导致性能问题?看起来查询已经足够快了。希望优化器能够在真正重要的情况下(即涉及大表的情况下)正确使用它。没有条件:
Table 'Customers'. Scan count 1, logical reads 2
条件是:
Table 'Customers'. Scan count 0, logical reads 60,
区别在于第一种情况下的扫描(速度很快,因为表很小)与通过索引进行的重复随机访问(速度不是很快,因为表太小,没有意义)
但请注意,所有这些由嵌套循环联接引起的重复逻辑读取不会导致实际的I/O(物理读取),因为它们会一次又一次地访问相同的几个块(这些块在缓冲区缓存工作集中)
这是否会导致性能问题?看起来查询已经足够快了。希望优化器能够在真正重要的情况下(即涉及大表的情况下)正确使用它。Merci,什么是工作表?这是用于收集连接数据的临时结构。第二个查询显然不需要它,因为这是通过索引访问直接拾取行。您可以为这两个查询附加执行计划。这应该会显示更多的细节。这里有:Hash Join(需要工作表)和Nested LoopMerci,什么是Worktable?这是用于收集连接数据的临时结构。第二个查询显然不需要它,因为这是通过索引访问直接拾取行。您可以为这两个查询附加执行计划。这应该会显示更多的细节。这里有:散列连接(需要工作表)和嵌套循环这很有趣。我将在OwenSQL安装中测试这一点。但现在,我要检查是否有销售索引。以custid为键、orderid和orderdate为包含列的订单这很有趣。我将在OwenSQL安装中测试这一点。但现在,我要检查Sales.Orders是否有索引,其中custid作为键,orderid和orderdate作为包含列