我正在设计一个带有单个表的数据库,用于我需要实现解决方案的特殊方案。该表在短时间后将有几亿行,但每行将相当紧凑。即使有很多行,我也需要插入,更新和选择速度才能快速,所以我需要为工作选择最佳索引。
我的表格如下:
create table dbo.Domain
(
Name varchar(255) not null,
MetricType smallint not null, -- very small range of values, maybe 10-20 at most
Priority smallint not null, -- extremely small range of values, generally 1-4
DateToProcess datetime not null,
DateProcessed datetime null,
primary key(Name, MetricType)
);
选择查询将如下所示:
select Name from Domain
where MetricType = @metricType
and DateProcessed is null
and DateToProcess < GETUTCDATE()
order by Priority desc, DateToProcess asc
第一种类型的更新将如下所示:
merge into Domain as target
using @myTablePrm as source
on source.Name = target.Name
and source.MetricType = target.MetricType
when matched then
update set
DateToProcess = source.DateToProcess,
Priority = source.Priority,
DateProcessed = case -- set to null if DateToProcess is in the future
when DateToProcess < DateProcessed then DateProcessed
else null end
when not matched then
insert (Name, MetricType, Priority, DateToProcess)
values (source.Name, source.MetricType, source.Priority, source.DateToProcess);
第二种类型的更新将如下所示:
update Domain
set DateProcessed = source.DateProcessed
from @myTablePrm source
where Name = source.Name and MetricType = @metricType
这些是最佳插入,更新和选择速度的最佳指标吗?
-- for the order by clause in the select query
create index IX_Domain_PriorityQueue
on Domain(Priority desc, DateToProcess asc)
where DateProcessed is null;
-- for the where clause in the select query
create index IX_Domain_MetricType
on Domain(MetricType asc);
答案 0 :(得分:4)
观察:
思路:
您的SELECT查询没有覆盖它的索引。你需要一个(DateToProcess, MetricType, Priority DESC) INCLUDE (Name) WHERE DateProcessed IS NULL
`:你必须尝试使用键列顺序来获得最佳的
您可以扩展该索引以使每个MetricType具有过滤索引(保持DateProcessed IS NULL过滤器)。当我有数百万行用
答案 1 :(得分:0)
在表架构部分中,您突出显示“MetricType”是两个主键之一,因此应该明确地将其与“名称”列一起编入索引。至于'Priority'和'DateToProcess'字段,因为这些字段将出现在where子句中,将它们编入索引也不会有害,但我不建议你对'DateProcessed'索引的where子句为null索引一组数据并不是一个好主意,删除它并索引这两列的全部内容。