Стоимость функции встроенной таблицы в SQL Server - PullRequest
3 голосов
/ 19 августа 2009

Существуют ли присущие SQL-серверу 2008 функции со встроенными табличными функциями, которые не возникают, если SQL-код встроен напрямую? Наше приложение очень активно использует функции со встроенными табличными значениями для повторного использования общих запросов, но недавно мы обнаружили, что запросы выполняются намного быстрее, если мы их не используем.

Учтите это:

CREATE FUNCTION dbo.fn_InnerQuery (@asOfDate DATETIME)
RETURNS TABLE
AS
RETURN
(
   SELECT ... -- common, complicated query here
)

Теперь, когда я сделаю это:

SELECT TOP 10 Amount FROM dbo.fn_InnerQuery(dbo.Date(2009,1,1)) ORDER BY Amount DESC

Запрос возвращается с результатами примерно через 15 секунд.

Однако, когда я делаю это:

SELECT TOP 10 Amount FROM 
(
   SELECT ... -- inline the common, complicated query here
) inline
ORDER BY Amount DESC

Запрос возвращается менее чем за 1 секунду.

Я немного сбит с толку из-за накладных расходов на использование табличной функции в этом случае. Я этого не ожидал. У нас есть тонна табличных функций в нашем приложении, поэтому мне интересно, есть ли здесь что-то, чего мне не хватает.

Ответы [ 4 ]

3 голосов
/ 19 августа 2009

В этом случае UDF должен быть неотнесен / расширен как представление, и он должен быть прозрачным.

Очевидно, это не ...

В этом случае я предполагаю, что столбец имеет значение smalldatetime и приводится к datetime из-за параметра udf, но константа корректно оценивается (для соответствия типу данных colum), когда она встроена.

datetime имеет более высокий приоритет, чем smalldatetime, поэтому столбец будет приведен

Что говорят планы запроса? UDF будет показывать сканирование, наиболее вероятным является поиск в строке (не на 100%, просто на основании того, что я видел раньше)

Редактировать: Сообщение в блоге Адама Мачаника

0 голосов
/ 19 августа 2009

Во втором примере функция Table Valued должна вернуть весь набор данных, прежде чем запрос сможет применить фильтр. Прыжок через границу TF - это не то, что оптимизатор всегда может сделать.

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

Если вы сравните планы двух запросов, вы увидите, что они разные.

0 голосов
/ 19 августа 2009

Попробуйте запустить табличную функцию независимо, чтобы увидеть, насколько быстро / медленно она выполняется?

Кроме того, я не уверен, как очистить кэш выполнения (?), Который SQL Server может сохранить от выполнения UDF. Я имею в виду - если вы сначала запускаете UDF, это может быть тот случай, когда SQL Server имеет фактический запрос и может кэшировать план / результат. Итак, если вы запустите сложный запрос отдельно - он может быть запущен из кеша.

0 голосов
/ 19 августа 2009

Одна вещь, которая может замедлять работу функций, это пропуск dbo. из таблицы ссылок внутри функции. Это приводит к тому, что SQL Server выполняет проверку безопасности для каждого вызова, что может быть дорогостоящим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...