Lookup、Scan 和 Seek 有什么区别?

What is the difference between Lookup, Scan and Seek?

所以我找到了这个查询

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.

...

Every individual seek, scan, lookup, or update on the specified index by one query execution is counted as a use of that index and increments the corresponding counter in this view. Information is reported both for operations caused by user-submitted queries, and for operations caused by internally generated queries, such as scans for gathering statistics.

现在我明白了,当我 运行 查询时,它获得了这 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

但我不明白用户用这些值表示的 table 做了什么。

那么 Lookup、Scan 和 Seek 的区别是什么?

这些操作的基本区别:

假设您有两个表。表A和表B。这两个表都包含超过 1000 000 行,并且都在 Id 列上有聚簇索引。 TableB 在代码列上也有非聚集索引。 (请记住,您的非聚集索引始终指向聚集索引的页面...)

求:

假设您只需要 TableA 中的 1 条记录,并且您的聚簇索引位于列 Id 上。 查询应如下所示:

SELECT Name
FROM TableA
WHERE Id = 1

您的结果包含的完整数据集不到 15%(介于 10-20 之间,视情况而定)...Sql服务器在此场景中执行索引查找。 (优化器已找到一个有用的索引来检索数据)

扫描:

比如你的查询需要TableA中超过15%的数据,那么就需要扫描整个索引来满足查询。 让我们考虑一下 TableB 将 TableA Id 列作为来自 TableA 的外键,并且 TableB 包含来自 TableA 的所有 Ids。查询应如下所示:

SELECT a.Id
FROM TableA a
JOIN TableB b ON a.Id = b.TableAId

或者只是

SELECT *
FROM TableA

对于 TableA 上的索引 SQL 服务器执行使用索引扫描。因为所有数据(页面)都需要满足查询...

查找:

让我们考虑一下 TableB 有列 dim 和列 code 以及 code 上的非聚集索引(正如我们提到的)。 SQL 服务器在需要从数据页中检索非关键数据时将使用查找,并使用非聚集索引来解析查询。 例如,可以在查询中使用键查找,例如:

SELECT id, dim
FROM TableB
WHERE code = 'codeX'
  • 可以通过覆盖索引来解决(包括dim到非聚集索引)