У нас есть хранилище данных с довольно большим количеством записей (10-20 миллионов строк), и мы часто выполняем запросы, которые подсчитывают записи между определенными датами или подсчитывают записи с определенными флагами, например
SELECT
f.IsFoo,
COUNT(*) AS WidgetCount
FROM Widgets AS w
JOIN Flags AS f
ON f.FlagId = w.FlagId
WHERE w.Date >= @startDate
GROUP BY f.IsFoo
Производительность не ужасная, но может быть относительно вялой (возможно, 10 секунд на холодном кэше).
Недавно я обнаружил, что могу использовать GROUP BY
в индексированных представлениях, и поэтому попробовал нечто похожее на следующее
CREATE VIEW TestView
WITH SCHEMABINDING
AS
SELECT
Date,
FlagId,
COUNT_BIG(*) AS WidgetCount
FROM Widgets
GROUP BY Date, FlagId;
GO
CREATE UNIQUE CLUSTERED INDEX PK_TestView ON TestView
(
Date,
FlagId
);
В результате производительность моего первого запроса теперь <100 мс, а результирующее представление и индекс <100 тыс. (Хотя количество строк у нас большое, диапазон дат и идентификаторов флагов означает, что это представление содержит только 1000-2000 строк).
Я думал, что, возможно, это подорвет производительность записи в таблицу Widget, но нет - насколько я могу сказать, производительность вставок и обновлений в эту таблицу практически не зависит (плюс, будучи хранилищем данных, эта таблица обновляется нечасто). так или иначе)
Мне это кажется слишком хорошим, чтобы быть правдой - не так ли? С чем мне следует быть осторожным при использовании индексированных представлений таким образом?
SELECT
иCREATE VIEW
сценарии не правы, так как я считаю, что вашCREATE INDEX
сценарий.Ответы:
Как вы заметили, само представление материализует только небольшое количество строк - поэтому даже если вы обновите всю таблицу, дополнительные операции ввода-вывода, связанные с обновлением представления, будут незначительными. Вы, вероятно, уже почувствовали самую большую боль, которую вы почувствуете, когда создали вид. Следующий ближайший будет, если вы добавите gazillion строк в базовую таблицу с кучей новых идентификаторов, которые требуют новых строк в представлении.
Это не слишком хорошо, чтобы быть правдой. Вы используете индексированные представления именно так, как они должны были использоваться - или, по крайней мере, один из наиболее эффективных способов: платить за будущие агрегаты запросов во время записи. Это работает лучше всего, когда результат намного меньше исходного и, конечно, когда агрегаты запрашиваются чаще, чем обновляются базовые данные (чаще встречается в DW, чем в OLTP, как правило).
К сожалению, многие люди думают, что индексирование представления - это волшебство - индекс не сделает все представления более эффективными, особенно представления, которые просто объединяют таблицы и / или производят такое же количество строк, что и источник (или даже умножают). В этих случаях ввод-вывод в представлении такой же или даже хуже, чем в исходном запросе, не только потому, что есть такие же или более строк, но часто они также хранят и материализуют больше столбцов. Таким образом, материализация их заранее не дает никакой выгоды, поскольку - даже с твердотельными накопителями - ввод-вывод, обработка и рендеринг сети и клиента по-прежнему остаются основными узкими местами при возврате больших наборов результатов клиенту. Экономия, которую вы получаете, избегая объединения во время выполнения, просто не поддается измерению по сравнению со всеми другими ресурсами, которые вы все еще используете.
Как и некластеризованные индексы, просто будьте осторожны, чтобы не переусердствовать. Если вы добавите 10 разных индексированных представлений в одну таблицу, вы увидите, как больше повлияет часть записи вашей рабочей нагрузки, особенно если столбцы группировки не являются ключом кластеризации.
Черт возьми, я собирался вести блог на эту тему.
источник
Ответы Аарона хорошо охватили этот вопрос. Две вещи, которые нужно добавить:
Я использовал как агрегирование, так и объединение представлений с исключительной выгодой
В целом ваш вариант использования кажется идеальным. Индексированные представления - это метод, который недостаточно используется.
источник