SQL Server 2008: объединение VIEW с другими VIEW: предварительный расчет без обращения к временным таблицам
Для выполнения преобразований в моей базе данных я часто использую цепочку представлений. В представлениях будут общие табличные выражения. Например, у меня было бы следующее:
CREATE VIEW TransformationStep1 AS
WITH Transformation1A AS (
SELECT Field1, Field2, Field3, Bla(Field1) AS Calc FROM Table1
),
Transformation1B AS (
SELECT Field1, Field2, Field3, Calc FROM Transformation1A
)
SELECT * FROM Transformation1B
CREATE VIEW TransformationStep2 AS
WITH Transformation2A AS (
SELECT Field1, Calc FROM TransformationStep1
), ....
Где-то рядом с TransformationStep4 представления будут замедляться по мере усложнения плана запроса. Это ожидается и ОК.
Но когда я хочу соединить часть TransformationStep4 с самим собой, запрос сильно замедлится, так как оптимизатор попытается вернуться обратно к исходным таблицам и искать какие-то индексы. Обычно это нормально, но иногда я просто хочу сохранить свой временный результат и присоединиться к нему, потому что (будучи специалистом по разработке в истории) я, например, знаю, что таблица результатов будет довольно маленькой, и к ней будет присоединяться гораздо быстрее против "предварительной выборки" этого.
Есть ли способ написать подсказку для запроса, которая повлияет на план запроса таким образом, что подзапрос будет предварительно выбран, а затем объединен? В противном случае мне придется прибегнуть к временным таблицам в хранимой процедуре, но я хочу избежать этого, если смогу.
Спасибо за любые предложения, даже если вы думаете, что мой дизайн отстой:-)
1 ответ
Представление - это расширяемый макрос: отсутствует предварительное вычисление для кэширования или предварительной выборки.
Если у вас нет индексированных представлений, где вы можете использовать NOEXPAND... но они не будут работать в обычных представлениях.
Однако вы также можете использовать внутренний TOP/ORDER BY, чтобы материализовать представление:
SELECT
*
FROM
(SELECT TOP 2000000000 * FROm TransformationStep2 ORDER BY soemthing) V1
JOIN
(SELECT TOP... ) bar on foo.x = bar.x
В представлении нет ничего волшебного: это просто текст, без памяти и постоянства...