Даты актуальности значений. Как правильно проиндексировать?

Максим М.
Дата: 02.02.2013 10:59:08
Добрый день, коллеги.
Бьюсь над следующей проблемой:
Есть таблица "Intervals", где для множества элементов хранятся значения с указанием диапазона актуальности этих значений по дате. Список полей:

ItemID - идентификатор элемента
ValueTypeID - тип значения
Value - значение
DateStart - дата начала актуальности значения
DateEnd - дата окончания актуальности значения

В таблице около 70млн записей, разных ItemID - несколько миллионов, разных ValueTypeID - несколько десятков.
Интервалы не пересекаются.
Самый частый запрос к таблице - суммирование всех значений определенного типа на определенную дату, вида:
select
	...
	sum(Value)
from
	Intervals i
	left join Dates d -- календарь
		on i.DateStart <= d.[Date]
		and i.DateEnd  >= d.[Date]
where
	i.ValueTypeID = ...
	and d.[Date] = ...
group by
	...


Самый удачный вариант индекса, который я пока придумал, это кластеризованный индекс по ValueTypeID, DateStart, DateEnd.
Если делать запрос ровно на одну дату - работает быстро. Если за серию дат (за все дни месяца) - значительно медленнее. А если еще к этому запросу, не дай бог, начать джойнить какие-либо свойства Item'ов по ItemID для дополнительных группировок - пиши пропало...
Как правильно проиндексировать таблицу Intervals, чтобы сервер мог быстро отбирать и группировать значения по дате? Или, быть может, есть какие-то хитрые приемы работы с такими таблицами?
Я уже настолько устал с ней бороться, что всерьез рассматриваю вариант записать в отдельную таблицу все известные значения всех Item'ов на каждую календарную дату :) Такая таблица будет иметь миллиарды записей и занимать много-много гигабайт, но ее хоть по датам проиндексировать можно будет по-человечески.
alexeyvg
Дата: 02.02.2013 12:01:58
Максим М.
Самый удачный вариант индекса, который я пока придумал, это кластеризованный индекс по ValueTypeID, DateStart, DateEnd.
Если делать запрос ровно на одну дату - работает быстро. Если за серию дат (за все дни месяца) - значительно медленнее.
Ну да, нормальный индекс - будет агрегирование интересующего сегмента данных, эффективнее ничего не придумать.

Максим М.
. А если еще к этому запросу, не дай бог, начать джойнить какие-либо свойства Item'ов по ItemID для дополнительных группировок - пиши пропало...
Нужно смотреть эти "другие запросы", скорее всего поможет такой индекс: ValueTypeID, ItemID, DateStart, DateEnd + include value
aleks2
Дата: 02.02.2013 15:32:11
1. MS SQL умеет делать index intersect. Поэтому
два индекса
ValueTypeID, DateStart
ValueTypeID, DateEnd.
могут помочь обрести щастье.

2.
from
	Intervals i
	left join Dates d -- календарь
		on i.DateStart <= d.[Date]
		and i.DateEnd  >= d.[Date]
where
	i.ValueTypeID = ...
	and d.[Date] = ...

вот нафега тут Dates? А сервер напрягается.

3. Чо, временные таблицы пользовать не обучены?
Максим М.
Дата: 02.02.2013 17:41:37
aleks2
1. MS SQL умеет делать index intersect. Поэтому
два индекса
ValueTypeID, DateStart
ValueTypeID, DateEnd.
могут помочь обрести щастье.

2.
from
	Intervals i
	left join Dates d -- календарь
		on i.DateStart <= d.[Date]
		and i.DateEnd  >= d.[Date]
where
	i.ValueTypeID = ...
	and d.[Date] = ...

вот нафега тут Dates? А сервер напрягается.

3. Чо, временные таблицы пользовать не обучены?


1. Спасибо за совет, попробую.
2. Dates тут для... черт, хороший вопрос :) Этот джойн я планировал спрятать в представлении, к которому могли бы обращаться менее искушенные в sql пользователи, чтобы с их точки зрения представление выглядело, как простая таблица где есть значения на каждую дату. И чтобы источник на занимал столько места на диске, сколько заняла бы "таблица где есть значения на каждую дату". Джойн, согласен, варварский. Может как-то проще можно...?
3. Как могут помочь временные таблицы?
Cygapb-007
Дата: 02.02.2013 18:19:18
Максим М.
3. Как могут помочь временные таблицы?
так же как и вложенные запросы, ятд:)