前言
我们在建立索引的时候,对于调节筛选列是大家都能够注意到的。但是对于包含列检查会被忽略。从而导致大量的LOOKUP ,也就是书签查找。
那么我如何才能找出某个表是不是执行了书签查找,执行了多少次书签查找呢?
正文
好消息是,SQL Server 有各种各样的动态管理视图,其中 sys.dm_db_index_operational_stats 视图就能查询到我们需要的信息。 这个视图的singleton_lookup_count列 就会返回执行了多少个查找操作。
让我们来看一个例子
先创建一个新表,并在单个列上创建非聚集索引。
CREATE TABLE Customers
(
CustomerID INT NOT NULL PRIMARY KEY CLUSTERED,
CustomerName CHAR(100) NOT NULL,
CustomerAddress CHAR(100) NOT NULL,
Comments CHAR(185) NOT NULL,
Value INT NOT NULL
)
GO
CREATE NONCLUSTERED INDEX idx_Test ON Customers(Value)
GO
插入数据
在表中插入80000行:
DECLARE @i INT = 1
WHILE (@i <= 80000)
BEGIN
INSERT INTO Customers VALUES
(
@i,
'CustomerName' + CAST(@i AS CHAR),
'CustomerAddress' + CAST(@i AS CHAR),
'Comments' + CAST(@i AS CHAR),
@i
)
SET @i += 1
END
GO
我们执行一个简单的查询,并使用查询提示 强制使用索引
SELECT * FROM Customers WITH (INDEX(idx_Test))
WHERE Value < 80001
GO
如下图可以看到,语句对表customer 执行了look up 书签查找
如下图所示,Key Lookup执行了8000次
当您现在查询动态管理函数sys.dm_db_index_operational_stats时,SQL Server会精确返回您执行了多少次查找操作
SELECT singleton_lookup_count, *
FROM sys.dm_db_index_operational_stats(DB_ID(), OBJECT_ID('Customers'), 1, NULL)
GO
如下图所示,使用查询得到的lookup 次数和实际的次数完全一致。
总结
书签查找LOOK UP 操作一般来说并没有什么问题。但是如果书签查找的次数非常多,就会对性能产生影响,导致查询运行缓慢。 在对数据库进行整体性能调优时,我们可以批量查询出来。使用下面的SQL 可以吧数据库中所有的lookup全部查询出来。
SELECT OBJECT_NAME(a.object_id)AS name,singleton_lookup_count,b.name
FROM sys.dm_db_index_operational_stats(DB_ID(), NULL, NULL, NULL) a ,sys.objects b
WHERE a.object_id=b.object_id
AND b.is_ms_shipped=0
ORDER BY singleton_lookup_count DESC