我有一个包含大约 200 万行的 SQL Server 表,该表存储简短的文本文档。这是我的架构:
CREATE TABLE Documents (
documentId bigint IDENTITY NOT NULL,
content nvarchar(MAX) NOT NULL,
isIndexed bit NOT NULL
)
我有一个单独的基于 Lucene 的索引器进程来执行此操作:
SELECT TOP 1 documentId, content FROM Documents WHERE isIndexed = 0
然后在执行此操作之前执行索引操作:
UPDATE Documents SET isIndexed = 1 WHERE documentId = @documentId
最初这工作得很好。当表中的每个文档都没有被索引(即所有isIndexed
值都是 0)时,每次检索大约需要 5 毫秒。
然而,随着越来越多的文档被索引,检索时间慢慢增加。目前大约是 150 毫秒 - 速度降低了 30 倍。我注意到 UPDATE 语句似乎总是在 2 毫秒内运行,所以我知道这不是问题。
从一开始,该表在 isIndexed 列上始终有一个非聚集索引,但实际执行计划显示 SQL Server 使用索引扫描(而不是搜索)。
我可以做些什么来加快系统速度?
我知道现有的“isIndexed”列本身很糟糕,但由于索引器的工作方式,它不能直接通过 documentId 请求文档。由于这个和其他原因,我不能接受任何不能解决眼前问题的答案。
由于选择性,位列上的索引根本没有帮助。您应该考虑过滤索引:
你还应该
ORDER BY documentId
在你的SELECT
.尽管您应该在暂存环境中对此进行测试,因为它可能对您有所帮助
SELECT
,但可能会用更昂贵的UPDATE
.该表(现在)具有以下非聚集索引:
和聚集索引:
我从这里更改了我的查询:
对此:
现在查询再次在 10 毫秒内执行。实际执行计划报告它正在对 IX_Indexed_ASC 和 IX_DocumentId_Indexed 执行两个索引查找操作。