Консервированный ответ :
В слишком многих случаях индексированное представление может решить ваши краткосрочные цели производительности, но через некоторое время станет контрпродуктивным.Поэтому, если вы решите использовать индексированное представление, вам может потребоваться стратегия выхода.Позвольте мне описать несколько распространенных проблем с индексированными представлениями.
Индексированные представления могут увеличить конфликт блокировок.
Это очень легко продемонстрировать.Создайте следующую таблицу:
CREATE TABLE dbo.ChildTable(ChildID INT NOT NULL
CONSTRAINT PK_ChildTable PRIMARY KEY,
ParentID INT NOT NULL,
Amount INT NOT NULL);
GO
На одной вкладке в SSMS запустите этот скрипт:
BEGIN TRAN;
INSERT INTO dbo.ChildTable(ChildID, ParentID, Amount)
VALUES(1,1,1);
На другой вкладке запустите похожую:
BEGIN TRAN;
INSERT INTO dbo.ChildTable(ChildID, ParentID, Amount)
VALUES(2,1,1);
ROLLBACK;
Обратите внимание, что обе вставки завершены, они не блокируют друг друга.Откатитесь на обе вкладки и создайте индексированное представление:
CREATE VIEW dbo.ChildTableTotals WITH SCHEMABINDING
AS
SELECT ParentID,
COUNT_BIG(*) AS ChildRowsPerParent,
SUM(Amount) AS SumAmount
FROM dbo.ChildTable
GROUP BY ParentID;
GO
CREATE UNIQUE CLUSTERED INDEX ChildTableTotals_CI
ON dbo.ChildTableTotals(ParentID);
Перезапустите две вставки.Обратите внимание, что второй не завершен;это заблокировано.Причина очень проста: первая вставка изменяет соответствующую запись в индексированном представлении, поэтому вставка получает и удерживает на нем блокировку.
Так же легко продемонстрировать, что при создании индексированного представлениявзаимные блокировки также могут стать более вероятными.
Примечание: это не проблема способа реализации индексированных представлений.Если вы развернете свою собственную сводную таблицу и разработаете триггеры, которые напрямую изменяют ее, чтобы поддерживать ее актуальность, вы столкнетесь с той же проблемой.Только если вы не ведете свою сводную таблицу все время, вы можете обойти эту проблему блокировки, но более подробное обсуждение этой проблемы выходит за рамки этого поста.
Редактировать: пример может показаться надуманным, но проблема, которую он демонстрирует, очень реальна и очень распространена.Индексированные представления в средах OLTP имеют ограниченное использование, потому что они серьезно увеличивают конфликт блокировки и вызывают много взаимоблокировок.Весьма распространено, что кто-то создает их в OLTP, но в конце концов удаляет, потому что они создают больше проблем, чем решают.
Существует два распространенных способа демонстрации проблем, вызванных параллелизмом: мы либо пишем циклы, а затем запускаем ихнесколько соединений, или явно начать транзакции в двух или более соединений.Я призываю всех придумать более простой способ продемонстрировать эту проблему.