dm_db_index_usage_stats 如何为 user_seeks 和用户扫描显示 0 而对于 user_lookups 显示大量?

Mar*_*own 5 sql-server sql-server-2008-r2

我可能不明白一些事情,但这是问题。

我已经对 dm_db_index_usage_stats 进行了查询。我注意到我的几个索引在 user_lookups 列中有很大的数字(650 万和 2 万),但这些在 user_seeks 和 user_scans 列中也有一个零。

我的理解(来自在线书籍)是 user_lookups 列计算书签查找。据我所知,这是数据库无法在索引中找到它需要的所有列,并且必须访问主表或剩余列的聚集索引的情况。但是,如果 SQL Server 从未对索引进行过搜索或扫描,为什么会这样做呢?

Mar*_*ith 8

user_lookups是到索引查找。原始扫描或查找将在另一个非覆盖索引上。

例如

CREATE TABLE T
(
X INT IDENTITY PRIMARY KEY,
Y INT CONSTRAINT UQ UNIQUE NONCLUSTERED,
Z CHAR(8000) NULL
)

INSERT INTO T(Y)
SELECT DISTINCT number 
FROM master..spt_values

GO

DECLARE @Z INT
SELECT @Z = Z
FROM T 
WHERE Y = 1

GO 1000
Run Code Online (Sandbox Code Playgroud)

给出以下方案

计划

SELECT index_id, user_seeks,user_scans, user_lookups
FROM sys.dm_db_index_usage_stats
WHERE object_id = object_id('T')
ORDER BY index_id
Run Code Online (Sandbox Code Playgroud)

在 NCI 上显示 1,000 次搜索,在 CI 上显示 1,000 次查找。

index_id    user_seeks           user_scans           user_lookups
----------- -------------------- -------------------- --------------------
1           0                    0                    1000
2           1000                 0                    0
Run Code Online (Sandbox Code Playgroud)

顺便说一句:以防万一您不知道user_lookups这里显示的是指包含查找运算符的计划执行的次数,而不是实际发生的查找次数。例如,尽管在现实中执行了 0 和 2,161 次查找,但以下两个都将计数器加 1

SELECT  Z
FROM T 
WHERE Y = -999

SELECT Z
FROM T WITH (FORCESEEK)
WHERE Y >= 0
Run Code Online (Sandbox Code Playgroud)

  • 不错,马丁。 (2认同)