【发布时间】:2020-04-18 10:20:52
【问题描述】:
我有一个table that's used as a queue:
create table items
(
itemId int, -- PK, identity
status int, -- Possible values: 0 = Pending, 1 = Processing, 2 = Processed
createdAt datetime2,
updatedAt datetime2,
content text
)
生产者将记录添加到队列中,消费者 FIFO 读取它们:
- 生产者添加状态为
Pending的记录,createdAt作为当前时间 - 消费者选择
Pending状态下的记录,按createdAt排序。消费时,他们将记录标记为Processing,并将updatedAt设置为当前时间(使用update/selectCTE) - 处理后,消费者将记录标记为
Processed - 在处理过程中,消费者可能会崩溃,因此无法将记录标记为
Processed - 当另一个消费者发现一条记录停留在
Processing状态超过 x 分钟(即updatedAt < current_time - x和status = Processing)时,他们会捡起并处理(假设新消费者不会崩溃;)) - 表有大约 100 万条记录,每天增长大约 20k
- 在任何给定时间都会有 Pending 和
Processing记录
我有 2 个问题
- 考虑到这种情况(尤其是最后 2 点),
(status, createdAt)上的索引是否包含updatedAt作为包含列?
我试过了,它表明索引被命中并且执行时间非常快(亚秒级)。但是,我不太确定这个低基数索引(起始列status)是一个好的索引,因为这样的索引是generally considered bad。我想知道它是否适用于我的情况,因为可能值的分布非常不均匀(Pending,InProgress,这是我要查询的。没有运行查询来选择 @ 987654343@ 个)。
- 我添加了包含的列 (
updatedAt) 以支持此过滤器status = Processing and updatedAt < current_time - x,但我不确定它是否有用。查询规划器关心包含的列还是只查看索引中的列 (status, createdAt)?
如果您回答两个问题,则可获得奖励积分;)
【问题讨论】:
标签: sql sql-server performance sql-tuning query-tuning