2009-11-12 5 views
1

Предположим, что у нас есть денормализованная таблица с примерно 80 столбцами и растет со скоростью ~ 10 миллионов строк (около 5 ГБ) в месяц. В настоящее время у нас есть 3 1/2 года данных (~ 400M строк, ~ 200 ГБ).Как повысить производительность нескалярных агрегатов в денормализованных таблицах

Мы создаем кластерный индекс для наилучшего соответствия извлечения данных из таблицы на следующие столбцы, которые служат в качестве основного ключа ...

[FileDate] ASC, 
    [Region] ASC, 
    [KeyValue1] ASC, 
    [KeyValue2] ASC 

... потому что, когда мы запрашиваем таблицу, мы всегда имеем весь первичный ключ.

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

SELECT 
    [Region] 
    , MAX([FileDate]) AS [FileDate] 
    FROM 
    HugeTable 
    GROUP BY 
    [Region] 

«Лучший» решение, которое я могу придумать, чтобы это создать некластерный индекс по региону. Хотя это означает дополнительную вставку на столе во время нагрузок, удар не минимален (мы загружаем 4 раза в день, поэтому менее 100 000 дополнительных вставок индексов на нагрузку). Так как таблица также разделена FileDate, результаты нашего запроса возвращаются достаточно быстро (200 мс или около того), и этот набор результатов кэшируется до следующей загрузки.

Однако я предполагаю, что у кого-то, у кого больше опыта хранения данных, может быть более оптимальное решение, поскольку по какой-то причине оно не «чувствует себя хорошо».

ответ

1

Я бы создал индекс покрытия (некластеризованный) на (Region, FileDate), а не только регион. Однако он будет большим, потому что у вас есть широкий кластеризованный ключ.

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

+0

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

1

Другим вариантом является наличие другой таблицы (Region, FileDate), которая содержит последние FileDate для каждого Region. Вы будете обновлять эту таблицу во время загрузки.

+0

Другой указатель на (Region, FileDate) будет проще, нет? – gbn

+0

Да, определенно проще. Я думал об объеме данных и b) время обновления. Чтобы получить последнее преимущество, вам понадобится знание Region, Max (FileDate) независимо от данных загрузки (в противном случае вы все равно закончите выполнение условных условий для каждой вставки). Если объем данных не является проблемой и/или количество обновлений не может быть уменьшено, как я описал, тогда лучший индекс покрытия будет лучшим. –

0

Любой шанс, что вы могли бы построить куб в Analysis Services, и запустить агрегацию запрос к кубу?

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