Индекс SQL Server - очень большая таблица с предложением where для очень небольшого диапазона значений - нужен ли мне индекс для предложения where? - PullRequest
4 голосов
/ 03 января 2012

Я проектирую базу данных с одной таблицей для специального сценария, для которого мне нужно реализовать решение. Через короткое время таблица будет иметь несколько сотен миллионов строк, но каждая строка будет довольно компактной. Даже когда строк много, мне нужно, чтобы скорости вставки, обновления и выбора были хорошими и быстрыми, поэтому мне нужно выбрать лучшие индексы для работы.

Мой стол выглядит так:

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

Ответы [ 3 ]

4 голосов
/ 03 января 2012

Наблюдения:

  • Ваши обновления должны использовать PK
  • Почему бы не использовать tinyint (диапазон 0-255), чтобы сделать строки еще более узкими?
  • вам нужно время?Вы можете использовать smallledatetime?

Идеи:

  • Ваш запрос SELECT не имеет индекса для его покрытия.Вы нуждаетесь в (DateToProcess, MetricType, Priority DESC) INCLUDE (Name) WHERE DateProcessed IS NULL `: вам придется поэкспериментировать с порядком ключевых столбцов, чтобы получить лучший

  • Вы можете расширить этот индекс, чтобы иметь фильтрованные индексы для MetricType также(сохраняя фильтр DateProcessed IS NULL.) Я сделал бы это после другого, когда у меня есть миллионы строк для тестирования с

1 голос
/ 03 января 2012

Я подозреваю, что ваша лучшая производительность будет достигнута при отсутствии индексов на Priority и MetricType.Количество элементов, вероятно, слишком мало, чтобы индексы приносили большую пользу.

Индекс на DateToProcess почти наверняка поможет, так как в этом столбце слишком высокая мощность, и он используется в * 1006.* и ORDER BY пункт.Сначала я бы начал с этого.

Поможет ли индекс на DateProcessed, вопрос для обсуждения.Это зависит от того, какой процент NULL значений вы ожидаете для этого столбца.Как обычно, лучше всего изучить план запроса с некоторыми реальными данными.

0 голосов
/ 03 января 2012

В разделе схемы таблицы вы подчеркнули, что «MetricType» является одним из двух первичных ключей, поэтому его обязательно следует индексировать вместе со столбцом «Имя». Что касается полей «Приоритет» и «DateToProcess», так как они будут присутствовать в предложении where, то их индексация также не помешает, но я не рекомендую, чтобы предложение where для этого индекса DateProcessed было нулевым индексация только набора данных не является хорошей идеей, удалите это и проиндексируйте все оба столбца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...