Почему подсказка READPAST приводит к игнорированию индексированных представлений?

10

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

Казалось, это хороший путь, потому что записи о финансовых транзакциях только добавляются, никогда не обновляются и не удаляются. Единственные строки, которые когда-либо будут пропущены, - это новые строки, вставленные в транзакцию; они фактически не существуют во внешнем мире, пока транзакция не будет совершена.

Тем не менее, я заметил худшую производительность запросов, использующих индексированные представления, на которые я READPASTнамекал. Сравнивая планы запросов, похоже, с подсказкой, оптимизатор запросов решает не использовать индексированное представление и вместо этого возвращается к обычному представлению.

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

SELECT TOP 1 isa.InvoiceId
FROM Financial_InvoiceSummaryAmounts isa WITH (READPAST)
WHERE isa.TotalOwedAmount = 0.0

введите описание изображения здесь

SELECT TOP 1 isa.InvoiceId
FROM Financial_InvoiceSummaryAmounts isa
WHERE isa.TotalOwedAmount = 0.0

введите описание изображения здесь

Добавление NOEXPANDподсказки также, похоже, работает, но мне интересно узнать больше о возможной причине, READPASTпо которой оптимизатор запросов сделал такой выбор в первую очередь (как часть полного ответа).

Марс
источник

Ответы:

7

Повторное использование таблицы примеров и индексированного представления из моей статьи Еще одна причина использовать NOEXPANDподсказки в Enterprise Edition :

CREATE TABLE dbo.T
(
    col1 integer NOT NULL
);
GO
INSERT dbo.T WITH (TABLOCKX)
    (col1)
SELECT 
    SV.number
FROM master.dbo.spt_values AS SV
WHERE 
    SV.type = N'P';
GO
CREATE VIEW dbo.VT
WITH SCHEMABINDING
AS
SELECT T.col1 
FROM dbo.T AS T;

репродукция

Этот запрос соответствует индексированному представлению (хотя и с избыточным агрегатом):

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT;

Индексированное представление соответствует

Добавление READPASTподсказки приводит к доступу к базовой таблице:

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT 
    WITH (READPAST);

Индексированное представление не соответствует

объяснение

READPASTНамек семантический воздействующим. Оптимизатор сопротивляется переписыванию запросов так, что результаты изменяются. Проиллюстрировать:

Следующий запрос выполняется без проблем:

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT 
    WITH (READPAST);

Однако:

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT 
    WITH (READPAST)
OPTION 
    (TABLE HINT (VT, FORCESCAN));

Выдает ошибку:

Msg 8722, уровень 16, состояние 1, строка 42
Невозможно выполнить запрос.
Семантическая влияющая подсказка readpast появляется в предложении WITH объекта VT
но не в соответствующем предложении 'TABLE HINT'.
Измените предложение OPTION (TABLE HINTS ...), чтобы семантика влияла на подсказки
соответствовать предложению WITH.

Когда вы ссылаетесь на индексированное представление без NOEXPANDподсказки, оно расширяется (до начала компиляции и оптимизации) для ссылки на базовые объекты. Позднее оптимизатор может рассмотреть возможность сопоставления дерева запросов с индексированным представлением, полностью или частично.

Когда READPASTиспользуется без NOEXPAND, подсказка распространяется на базовую таблицу, предотвращая сопоставление представлений (другая семантика).

С помощью NOEXPAND, подсказка относится к представлению напрямую, поэтому проблем нет.

Пол Уайт 9
источник