Как индексировать таблицу с медленно изменяющимся типом 2 для оптимальной производительности - PullRequest
4 голосов
/ 08 января 2010

Предположим, у вас есть таблица с медленно меняющимся размером типа 2.

Давайте выразим эту таблицу следующим образом со следующими столбцами:

* [Key]
* [Value1]
* ...
* [ValueN]
* [StartDate]
* [ExpiryDate]

В этом примере давайте предположим, что [StartDate] фактически является датой, когда значения для данного [Key] становятся известными системе. Таким образом, наш первичный ключ будет состоять из [StartDate] и [Key].

Когда поступает новый набор значений для данного [Ключа], мы присваиваем [ExpiryDate] некоторому предварительно определенному высокому суррогатному значению, такому как '12/31/9999'. Затем мы устанавливаем для существующих «самых последних» записей для этого [Ключа] значение [ExpiryDate], равное [StartDate] нового значения. Простое обновление на основе соединения.


Так что, если мы всегда хотели получить самые последние записи для данного [Ключа], мы знаем, что можем создать кластеризованный индекс, который будет:

* [ExpiryDate] ASC
* [Key] ASC

Хотя пространство клавиш может быть очень широким (скажем, миллион ключей), мы можем минимизировать количество страниц между чтениями, предварительно упорядочив их по [ExpiryDate]. И поскольку мы знаем, что самая последняя запись для данного ключа всегда будет иметь [ExpiryDate] «12/31/9999», мы можем использовать это в наших интересах.

Однако ... что если мы хотим получить моментальный снимок всех [Ключей] в данный момент времени? Теоретически, все пространство ключей не обновляется одновременно. Поэтому для заданного момента времени окно между [StartDate] и [ExpiryDate] является переменным, поэтому упорядочение по [StartDate] или [ExpiryDate] никогда не приведет к результату, в котором все записи, которые вы ищете смежный. Конечно, вы можете немедленно выбросить все записи, в которых [StartDate] больше, чем определенное вами время.


В сущности, в типичной СУБД, какая стратегия индексирования дает наилучший способ минимизировать количество операций чтения для получения значений для всех ключей для заданного момента времени? Я понимаю, что могу хотя бы максимизировать IO, разделив таблицу по [Key], однако это, конечно, не идеально.

В качестве альтернативы, есть ли другой тип медленно меняющихся измерений, который решает эту проблему более производительным образом?

Ответы [ 2 ]

1 голос
/ 09 января 2010

Ленивый DBA

Вы говорите о возвращении всех значений в вашей таблице измерений? Если так, то почему бы не добавить некластеризованный индекс с дополнительным покрытием, чтобы вы извлекали значения только из самого индекса, а не из таблицы? Таким образом, вы сканируете B-Tree с некоторыми прикрепленными «покрытыми» значениями, а не выполняете сканирование таблицы? Я не могу ручаться за относительную производительность, но стоит протестировать сценарий, над которым вы явно работаете.

Приветствия

Ozziemedes http://ozziemedes.blogspot.com/

0 голосов
/ 26 октября 2016

Если это действительно таблица «медленно меняющихся измерений», я бы рассмотрел кластеризованный индекс columnstore. Я знаю, что это было недоступно, когда вы задали вопрос, но все равно. Вы найдете отличную документацию здесь: «https://msdn.microsoft.com/en-us/library/gg492088.aspx" и здесь «http://www.nikoport.com/2013/07/05/clustered-columnstore-indexes-part-1-intro/".

Теперь, если вы хотите придерживаться индексов хранилища строк, если вы вставляете данные в таблицу последовательно, то в прошлом я использовал поле идентификаторов. ваши запросы будут выглядеть примерно так:

    declare @id;
    select @id = min(ID) from table where date = '12/31/9999';
    select fields from table where key = 112 and id > @id; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...