Повторное использование sql с представлением или функцией
У меня есть запрос sql, который я буду повторно использовать в нескольких хранимых процедурах. Запрос работает с несколькими таблицами и возвращает целочисленное значение на основе двух переданных ему переменных.
Вместо повторения запроса в разных хранимых процедурах я хочу поделиться им и иметь 2 варианта:
- создать представление, к которому я могу присоединиться, на основе переменных и получить от него целочисленное значение.
- снова создать функцию с критериями, переданными ей, и вернуть целочисленную переменную
Я склоняюсь к варианту 1, но мне хотелось бы, чтобы мнения о них были лучше и распространены. Который будет лучше работать с умными и т.д. (Присоединение к функции просмотра или вызова)
EDIT: СУБД - это SQL Server
Ответы
Ответ 1
Если вы всегда будете использовать тот же параметризированный предикат, чтобы отфильтровать результаты, я бы пошел на параметризованную встроенную функцию с табличной оценкой. В теории это рассматривается так же, как вид, поскольку они оба раскрываются оптимизатором на практике, что он может избежать проблем с предикатом. Пример такого случая можно увидеть во второй части в этой статье.
Как замечает Андомар в комментариях, большую часть времени оптимизатор запросов делает хорошую работу по преодолению предиката туда, где он нужен, но я не знаю об обстоятельствах, при которых использование встроенного TVF будет хуже работать так что это кажется рациональным выбором по умолчанию между двумя (очень похожими) конструкциями.
Единственным преимуществом, которое я могу видеть для представления, является то, что он позволит вам выбирать без фильтра или с различными фильтрами, поэтому он более универсален.
Встраиваемые TVF также могут использоваться для замены скалярных UDF для повышения эффективности как в этом примере.
Ответ 2
Вы не можете передавать переменные в представление, поэтому ваш единственный вариант - использовать функцию. Для этого есть два варианта:
- функция SCALAR
- Функция TABLE-VALUED (встроенная или многопозиционная)
Если вы возвращали записи, вы могли бы использовать предложение WHERE из-за не слишком сложного VIEW, которое может быть выровнено в запросе в представлении, но поскольку все, что вы возвращаете, является одним столбцом integer value
, тогда представление не будет работать.
Встроенный 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
Ответ 3
Я собираюсь дать вам половину ответа, потому что я не могу быть уверен в том, что лучше с точки зрения производительности, извините. Но тогда другие люди наверняка получили хорошие советы на этот счет, я уверен.
Я буду придерживаться вашей части "обычной практики".
Таким образом, дерево скалярных функций кажется мне естественным решением в этом случае. Почему вам нужно только значение, возвращаемое целочисленное значение - для чего нужны скалярные функции, не так ли?
Но тогда, если бы я мог видеть вероятность того, что позже мне понадобится больше одного значения, я мог бы подумать о переходе на TVF. Опять же, что, если вы уже реализовали свою скалярную функцию и использовали ее во многих местах вашего приложения, и теперь вам нужна строка, столбец или таблица значений, которые будут возвращены с использованием в основном той же логики?
По моему мнению (каламбур не предназначен), представление может стать чем-то вроде самого общего общего делителя как для скалярных, так и для табличных функций. Функции должны были бы только применять параметры.
Теперь вы сказали, что только планируете выбрать, какой вариант использовать. Тем не менее, учитывая вышеизложенное, я все же считаю, что взгляды могут быть хорошим выбором и оказаться полезными при масштабировании вашего приложения, и вы могли бы использовать оба представления и функции (если бы это не сильно расстроило производительность), как и я описано.
Ответ 4
Одно из преимуществ, которое имеет TVF, заключается в том, что вы можете заставить любого, кто его называет, нацеливать на определенный индекс.