在GUID的WHERE子句中使用LIKE会导致全表扫描

时间:2019-07-03 19:58:03

标签: sql-server sql-server-2012

我有一个看起来像这样的表:

CREATE TABLE Records 
(
    ID UNIQUEIDENTIFIER PRIMARY KEY NONCLUSTERED,
    owner UNIQUEIDENTIFIER,
    value FLOAT,
    timestamp DATETIME
)

在其他一些与此问题无关的列上有一个多列聚簇索引。

该表当前大约有500,000,000行,我需要在该表上进行操作,但是该表太大而无法处理(我被缓慢的硬件所阻碍)。因此,我决定分批处理它。

但是如果我说

SELECT ID 
FROM records
WHERE ID LIKE '0000%'

执行计划显示已扫描整个表。我以为有了索引,只有符合原始条件的那些行才会被扫描,直到SQL到达“ 0001”记录为止。将%放在前面,我可以清楚地看到为什么它会扫描整个表格。但是以%结尾时,它不必扫描整个表。

我猜测这与GUID而不是CHARVARCHAR列不同。

所以我的问题是这样的:如何在不扫描整个表的情况下搜索GUID的子部分?

1 个答案:

答案 0 :(得分:2)

从您的评论中,我看到了实际的需要是将随机GUID值的行根据范围分成大块(有序)。在这种情况下,您可以指定一个范围而不是LIKE以及最后一组中所需开始/结束值的过滤器:

SELECT ID
FROM dbo.records
WHERE
    ID BETWEEN '00000000-0000-0000-0000-000000000000'
    AND '00000000-0000-0000-0000-000FFFFFFFFF';

This article解释了如何在SQL Server中存储和排序唯一标识符(GUID),如何比较最后一个组并对其进行排序,而不是像您期望的那样从左到右进行排序。通过对最后一组进行过滤,您将获得一个可修饰的表达式,并仅触摸指定范围内的那些行(假设使用了ID上的索引)。