Lookup,Scan和Seek有什么区别?

时间:2017-05-14 22:59:56

标签: sql-server terminology

所以我找到了这个查询

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_idobject_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之间的区别是什么?

1 个答案:

答案 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'
  • 您可以通过覆盖索引(包括昏暗到非聚集的)来解决它