[英]Why would an index seek show high scan count in statistics?
没有太多细节,我有一个查询使用所有聚集和非聚集索引搜索产生执行计划(听起来很有希望)。 不幸的是,查询表现不佳,我很难理解为什么。
我正在使用set statistics io on
,可以看到其中一个表产生了大量的扫描和逻辑/物理读取:
SET statistics io ON
go
SELECT order_number,
audit_id,
orderadmission_net_paid_delta / 100.00,
'Admission',
orderadmission_net_paid_delta / 100.00,
performance_gl_description1,
section_data1,
performance_gl_code,
price_type_data1,
year(performance_start_date),
month(performance_start_date),
paymentmethod_type,
paymentmethod_name,
''
FROM JCRProdReplication.dbo.ts_audit WITH (NOLOCK)
JOIN JCRProdReplication.dbo.ts_order_admission WITH (NOLOCK)
ON orderadmission_audit_id = audit_id
LEFT JOIN JCRProdReplication.dbo.ts_order WITH (NOLOCK)
ON order_id = orderadmission_order_id
LEFT JOIN JCRProdReplication.dbo.ts_performance WITH (NOLOCK)
ON performance_id = orderadmission_performance_id
LEFT JOIN JCRProdReplication.dbo.ts_seat WITH (NOLOCK)
ON seat_id = orderadmission_seat_id
LEFT JOIN JCRProdReplication.dbo.ts_section WITH (NOLOCK)
ON section_id = seat_section_id
LEFT JOIN JCRProdReplication.dbo.ts_price_type WITH (NOLOCK)
ON price_type_id = orderadmission_price_type_id
LEFT JOIN JCRProdReplication.dbo.ts_order_payment WITH (NOLOCK)
ON orderpayment_audit_id = audit_id
LEFT JOIN JCRProdReplication.dbo.ts_payment_method WITH (NOLOCK)
ON paymentmethod_id = orderpayment_paymentmethod_id
WHERE audit_time >= '20140107'
AND audit_time < '20140108'
(72174 row(s) affected)
Table 'ts_payment_method'. Scan count 0, logical reads 4180, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ts_price_type'. Scan count 0, logical reads 4184, physical reads 26, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ts_section'. Scan count 0, logical reads 4184, physical reads 28, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ts_seat'. Scan count 0, logical reads 6276, physical reads 2240, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ts_performance'. Scan count 0, logical reads 4184, physical reads 50, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ts_order'. Scan count 0, logical reads 8368, physical reads 820, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ts_order_admission'. Scan count 71877, logical reads 288490, physical reads 44104, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ts_audit'. Scan count 1, logical reads 252, physical reads 5, read-ahead reads 246, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
在理解为什么索引搜索会在统计中显示大量扫描/读取时,我的下一步是什么? (我一直在谷歌搜索,没有找到解释)。
STATISTICS IO
报告的扫描计数可能不是您的想法。
例
USE tempdb;
SET NOCOUNT ON;
CREATE TABLE Num1 (N INT PRIMARY KEY);
CREATE TABLE Num2 (N INT);
CREATE CLUSTERED INDEX IX ON Num2(N);
INSERT INTO Num1
OUTPUT inserted.N
INTO Num2
SELECT number
FROM master..spt_values
WHERE type = 'P'
AND number BETWEEN 1 AND 1000
SET STATISTICS IO ON;
SELECT *, sys.fn_PhysLocFormatter(N2.%%physloc%%)
FROM Num1 N1
INNER LOOP JOIN Num2 N2
ON N1.N = N2.N
SET STATISTICS IO OFF;
DROP TABLE Num1, Num2
给出计划
并输出
Table 'Num2'. Scan count 1000, logical reads 2002
Table 'Num1'. Scan count 1, logical reads 3
尽管计划显示寻求1000扫描报告。
由于索引未声明为唯一,因此每次搜索都是部分扫描。 索引被搜索到1000次,然后在每个搜索它需要扫描索引,直到它找到第一行不匹配的数字。
Num2.IX
索引具有单个根页面和两个叶页面。
2,002个逻辑读取分解如下。
大多数搜索都需要两次读取(单个根页面和单个叶子页面)。 其中两个搜索(对于我的情况下的数字622和623)在读取两个叶页时都进行了三次逻辑读取。
这些是第一页叶子页面上的最后一行,第二页面上分别是第一行。
对于数字622
它需要读取下一页的下一行以查看它是否重复。 对于数字623
,解释是索引的结构如下。
根页面具有可能包含在每个较低页面上的最低值。 由于索引未声明为唯一,因此在跨越页边界的多个匹配行的情况下也需要检查上一页。
以下博客文章提供了有关解释STATISTICS IO
输出的一些其他说明。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.