Как индексировать таблицу с медленно меняющимся измерением типа 2 для оптимальной производительности

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

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

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

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

Когда для данного [Key] поступает новый набор значений, мы присваиваем [ExpiryDate] какое-то предопределенное старшее суррогатное значение, например «31.12.9999». Затем мы устанавливаем существующие «самые последние» записи для этого [Key] так, чтобы [ExpiryDate] был равен [StartDate] нового значения. Простое обновление на основе соединения.


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

* [ExpiryDate] ASC
* [Key] ASC

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

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


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

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


person The Lazy DBA    schedule 08.01.2010    source источник
comment
Вы используете службы Analysis Services?   -  person adolf garlic    schedule 22.01.2010


Ответы (2)


Ленивый администратор баз данных

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

Ваше здоровье

Оззимедес http://ozziemedes.blogspot.com/

person Ozziemedes    schedule 09.01.2010

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

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

    declare @id;
    select @id = min(ID) from table where date = '12/31/9999';
    select fields from table where key = 112 and id > @id; 
person dier    schedule 26.10.2016