所以我找到了这个查询
SELECT MAX(us.[last_user_lookup]) as [last_user_lookup], MAX(us.[last_user_scan])
AS [last_user_scan], MAX(us.[last_user_seek]) as [last_user_seek]
from sys.dm_db_index_usage_stats as us
where us.[database_id] = DB_ID() AND us.[object_id] = OBJECT_ID('tblName')
group by us.[database_id], us.[object_id];
当我查看sys.dm_db_index_usage_stats上的文档时,所有内容都是
last_user_seek datetime Time of last user seek last_user_scan datetime Time of last user scan. last_user_lookup datetime Time of last user lookup.
...
通过一次查询执行对指定索引的每个人进行搜索,扫描,查找或更新都将计为该索引的使用,并在此视图中递增相应的计数器。报告的信息既包括由用户提交的查询引起的操作,也包括由内部生成的查询引起的操作,例如收集统计信息的扫描。
现在我了解到,当我运行查询时,它会获得这3个字段的最高时间,因为sys.dm_db_index_usage_stats
可以有重复database_id
和object_id
,其中一个或多个字段也可能是NULL
(所以你只能到SELECT TOP 1 ... ORDER BY last_user_seek, last_user_scan, last_user_lookup DESC
,否则你可能会错过数据)但是当我运行它时,我会得到像
NULL | 2017-05-15 08:56:29.260 | 2017-05-15 08:54:02.510
但我不明白用户对这些值表示的表做了什么。
那么Lookup,Scan和Seek之间的区别是什么?
答案 0 :(得分:5)
这些操作之间的基本区别:
让我们考虑你有两张桌子。表A和表B.这两个表都包含超过1000,000行,并且都在Id列上具有聚簇索引。 TableB在代码列上也有非聚集索引。 (请记住,您的非聚簇索引始终指向聚簇索引的页面...)
<强>求:强>
让我们考虑您只需要TableA中的1条记录,并且Clustered index位于列Id上。 查询应该如下:
SELECT Name
FROM TableA
WHERE Id = 1
您的结果包含的完整数据集少于15%(介于10-20之间,具体取决于具体情况)...在此方案中搜索Sql server preform index。 (优化器找到了一个有用的索引来检索数据)
<强>扫描强>
例如,您的查询需要来自TableA的数据的15%以上,那么必须扫描整个索引以满足查询。 让我们考虑TableB将TableAId列作为TableA中的forgein键,TableB包含TableA中的所有ID。查询应该如下:
SELECT a.Id
FROM TableA a
JOIN TableB b ON a.Id = b.TableAId
或者只是
SELECT *
FROM TableA
对于TableA上的索引SQL Server预先形式使用索引扫描。因为所有数据(页面)都需要满足查询...
<强>查找强>
让我们考虑TableB在代码上有列dim以及列代码和非聚簇索引(如我们所提到的)。 SQL SERVER将在需要从数据页检索非关键数据时使用查找,并使用非聚簇索引来解析查询。 例如,密钥查找可以在查询中使用,如:
SELECT id, dim
FROM TableB
WHERE code = 'codeX'