повторно использовать SQL с видом или функцией - PullRequest
15 голосов
/ 27 января 2011

У меня есть SQL-запрос, который я буду повторно использовать в нескольких хранимых процедурах. Запрос работает с несколькими таблицами и возвращает целочисленное значение, основанное на 2 переданных ему переменных.

Вместо того, чтобы повторять запрос в разных хранимых процедурах, я хочу поделиться им и иметь 2 варианта:

  1. создать представление, к которому я могу присоединиться, на основе переменных и получить из него целочисленное значение.
  2. создайте функцию заново с переданными ей критериями и верните целочисленную переменную

Я склоняюсь к варианту 1, но хотел бы мнения о том, что является лучшей и обычной практикой. Что было бы лучше с точки зрения производительности и т. Д. (Присоединение к представлению или вызову функции)

РЕДАКТИРОВАТЬ: СУБД является SQL Server

Ответы [ 4 ]

13 голосов
/ 27 января 2011

Если вы всегда будете использовать один и тот же параметризованный предикат для фильтрации результатов, я бы использовал параметризованную встроенную табличную функцию.Теоретически это трактуется так же, как и View, поскольку оптимизатор оптимизирует их оба. На практике это позволяет избежать проблем с предикатами.Пример такого случая можно увидеть во второй части этой статьи .

. Как отмечает Андомар в комментариях, большую часть времени оптимизатор запросов хорошо выполняет толчок.до предиката, где это необходимо, но я не знаю ни одного обстоятельства, при котором использование встроенного TVF будет работать хуже, так что это кажется рациональным выбором по умолчанию между двумя (очень похожими) конструкциями.

ОдинЯ вижу преимущество для View в том, что оно позволит вам выбирать без фильтра или с другими фильтрами, что делает его более универсальным.

Встроенные TVF также могут использоваться для замены скалярных UDF для повышения эффективности как в этом примере .

1 голос
/ 27 января 2011

Вы не можете передавать переменные в представление, поэтому вам кажется, что вы можете использовать только одну функцию.Для этого есть два варианта:

  • функция SCALAR
  • функция TABLE-VALUED (встроенная или многократная инструкция)

Если вы возвращалисьзаписей, тогда вы можете использовать предложение WHERE вне не слишком сложного VIEW, которое может быть встроено в запрос в представлении, но поскольку все, что вы возвращаете, это один столбец integer value, то представление выиграло 't работать.

Встроенный TVF может быть расширен оптимизатором запросов для совместной работы с внешним (вызывающим) запросом, поэтому он может быть быстрее в большинстве случаев по сравнению с функцией SCALAR.

Однако использование отличается - функция SCALAR немедленно возвращает одно значение

select dbo.scalarme(col1, col2), other from ..

, тогда как inline-TVF требует, чтобы вы либо запросили его, либо CROSS APPLY для другой таблицы

select (select value from dbo.tvf(col1, col2)), other from ..

-- or

select f.value, t.other
from tbl t
CROSS apply dbo.tvf(col1, col2) f   -- or outer apply
0 голосов
/ 09 июля 2015

Одно преимущество TVF перед просмотром состоит в том, что вы можете заставить любого, кто его вызывает, указывать определенный индекс.

0 голосов
/ 27 января 2011

Я собираюсь дать вам полу-ответ, потому что я не могу быть уверен в том, что лучше с точки зрения производительности, извините. Но тогда я уверен, что другие люди получили хорошие советы на этот счет.

Я буду придерживаться вашей части «общей практики».

Итак, дерево скалярных функций кажется мне естественным решением в этом случае. Почему вы хотите, чтобы значение, целочисленное значение было возвращено - для этого и нужны скалярные функции?

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

На мой взгляд (без каламбура) представление может стать чем-то вроде наибольшего общего делителя для скалярных и табличных функций. Функции должны будут только применять параметры.

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

...