Является ли DB_NAME () детерминированной функцией? - PullRequest
1 голос
/ 08 марта 2012

У меня есть несколько баз данных, каждая из которых имеет таблицу, скажем, products.

Одна из этих баз данных («основная») содержит продукты, которые должны быть видны из всех баз данных.

Я делаю это, имея allproducts представление следующим образом:

CREATE VIEW allproducts AS
   SELECT col[...] FROM products
   UNION ALL SELECT col[...] FROM master.dbo.products;

Это работает хорошо, за исключением того, что представление allproducts основной базы данных нуждается в определении, которое не вносит свои собственные продукты:

CREATE VIEW allproducts AS
   SELECT col[...] FROM products;

Чтобы немного упростить вещи, я хотел бы иметь общее определение представления, что-то вроде следующего:

CREATE VIEW allproducts AS
   SELECT col[...] FROM products
   UNION ALL SELECT col[...] FROM master.dbo.products
     WHERE (DB_NAME() <> 'master');

Это работает , но я беспокоюсь о производительности. Итак, является ли функция DB_NAME() детерминированной, и если да, будет ли SQL Server сокращать всю правую часть UNION ALL на основе сравнения?

Если DB_NAME() оценивается для каждой строки master.dbo.products, есть ли более чистый способ сделать это, или я должен поддерживать отдельные определения представлений?

ОБНОВЛЕНИЕ: «Все функции метаданных недетерминированы. Это означает, что эти функции не всегда возвращают одинаковые результаты при каждом вызове, даже с одним и тем же набором входных значений». - http://msdn.microsoft.com/en-us/library/ms187812.aspx

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

Так что на основную часть вопроса дан ответ. Несмотря на то, что DB_NAME () является недетерминированным, планы выполнения одинаковы для вызова детерминированной UDF по сравнению с вызовом DB_NAME (), а производительность указывает, что результат DB_NAME () действительно сокращает другие ветви запроса , Они не так быстры, как скалярное сравнение, такое как «0 = 1» в предложении WHERE, поэтому даже детерминированные функции не полностью оптимизируют план. Я могу жить с UDF, поэтому я собираюсь пойти в этом направлении для этой ситуации.

Ответы [ 2 ]

0 голосов
/ 16 марта 2012

«Все функции метаданных являются недетерминированными. Это означает, что эти функции не всегда возвращают одинаковые результаты при каждом вызове, даже с одним и тем же набором входных значений».- http://msdn.microsoft.com/en-us/library/ms187812.aspx

В итоге я не включил DB_NAME () и просто поддерживал две версии каждого DDL.Раздражает, но даже функция UDF, возвращающая постоянное битовое значение, оказалась не такой эффективной, как я надеялся.

0 голосов
/ 08 марта 2012

Я настоятельно рекомендую не полагаться на короткое замыкание SQL Server, даже в тех случаях, когда вы подтвердили, что он работает сегодня, в текущей сборке, с текущими данными, на текущем оборудовании и т. Д. Единственное место, где SQL Сервер гарантирует короткое замыкание, AFAIK, находится внутри выражения CASE. И даже там у оптимизатора есть более важные правила, которым нужно следовать (например, короткое замыкание может прерваться при использовании агрегата).

Вы действительно думаете, что ваша главная проблема оптимизации будет состоять в том, оценивается ли DB_NAME() для каждой строки? Я вполне уверен, что этого не произойдет, но если это соломинка, которая убивает вашу производительность, безусловно, есть более важные проблемы, которые нужно решить.

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