SQL Server索引 - 非常大的表,其中where子句针对非常小的值 - 我需要where子句的索引吗?

时间:2012-01-03 16:10:28

标签: sql-server sql-server-2008 tsql

我正在设计一个带有单个表的数据库,用于我需要实现解决方案的特殊方案。该表在短时间后将有几亿行,但每行将相当紧凑。即使有很多行,我也需要插入,更新和选择速度才能快速,所以我需要为工作选择最佳索引。

我的表格如下:

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);

2 个答案:

答案 0 :(得分:4)

观察:

  • 您的更新应使用PK
  • 为什么不使用tinyint(范围0-255)使行更窄?
  • 你需要约会时间吗?你能用smallledatetime吗?

思路:

  • 您的SELECT查询没有覆盖它的索引。你需要一个(DateToProcess, MetricType, Priority DESC) INCLUDE (Name) WHERE DateProcessed IS NULL `:你必须尝试使用​​键列顺序来获得最佳的

  • 您可以扩展该索引以使每个MetricType具有过滤索引(保持DateProcessed IS NULL过滤器)。当我有数百万行用

  • 进行测试时,我会在另一个之后执行此操作

答案 1 :(得分:0)

在表架构部分中,您突出显示“MetricType”是两个主键之一,因此应该明确地将其与“名称”列一起编入索引。至于'Priority'和'DateToProcess'字段,因为这些字段将出现在where子句中,将它们编入索引也不会有害,但我不建议你对'DateProcessed'索引的where子句为null索引一组数据并不是一个好主意,删除它并索引这两列的全部内容。