откладывая n: m поиск хранимой процедуры - PullRequest
2 голосов
/ 25 мая 2011

У меня есть набор объектов, которые могут быть членами одного или нескольких из небольшого числа наборов (представьте себе объекты, которые могут находиться в нескольких местах внутри дерева). Поскольку эти назначения необходимо запрашивать часто и быстро, мы сохраняем их как один идентификатор «созвездия» в объекте, а затем сохраняем таблицу с идентификаторами созвездия, где каждое созвездие сопоставляется с несколькими наборами (это также спасает нас от некоторых проблема, связанная с отчетливостью, в отличие от наборов INNER JOIN, куда ГДЕ устанавливается (() подход, который может показаться более очевидным).

Пример: оба объекта 1 и 2 назначены наборам 3 и 4. Вместо хранения списка n: m

object id | set id
1           3
1           4
2           3
2           4

мы храним идентификатор созвездия 5 для объектов 1 и 2, затем имеем таблицу, присваивающую наборы 3 и 4 для созвездия 5. Поскольку объекты, как правило, присваиваются общим комбинациям наборов, это практически осуществимо на практике, т.е. Не нужно сохранять весь сценарий наихудшего случая из 2 ^ | множеств | различные созвездия вокруг.

Запрашивая все объекты в пределах хотя бы одного из видимых в настоящее время наборов s1, s2, ..., мы находим все созвездия, содержащие s1 или s2 или ..., а затем создаем запрос WHERE constellation IN (constellation1, constellation2, constellation3, ...)

Теперь мы переходим от Access к SQL Server, и вопрос заключается в том, следует ли нам изменить этот подход, поскольку мы фактически начинаем создавать все большие и большие IN-предложения.

Мой вопрос таков: будет ли это вариант использования хранимой процедуры? Я хотел бы иметь хранимую процедуру, как

SELECT * FROM объектов, ГДЕ IsInSet (s1, s2)

где этот список наборов переводится в соответствующий набор созвездий, и функция возвращает true, если созвездие объекта содержится в этом наборе. Поскольку я только перехожу на SQL Server и никогда не использовал хранимые процедуры, любые отзывы о том, будет ли это иметь смысл, будут высоко оценены. В частности, мне интересно, будет ли MSSQL оптимизировать это таким образом, чтобы таблица совокупности для установки становилась кэшированной, как в настоящее время мы делаем вручную для создания запросов.

1 Ответ

1 голос
/ 25 мая 2011

Похоже, у вас есть некоторая путаница относительно различий между FUNCTIONS и STORED PROCEDURES.

Хранимые процедуры - это именно то, что подразумевает название - хранимые операторы SQL, которые выполняются впартия, и может принимать параметры.Они в основном используются для создания согласованного кода и / или планов выполнения, а также для упрощения сложных процессов, делая их более модульными и разделенными.Они также удобны для повторного использования кода.

Определяемые пользователем функции передают параметры и возвращают либо скалярное значение, либо таблицу, и могут использоваться внутри запросов для возврата значений, которые назначены переменнымили значения строк (как в операторе UPDATE).

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

Редактировать:

Альтернативой UDF было бы использование предложения Существует.Не зная структуры вашей таблицы, что-то вроде:

SELECT *
FROM objects o
WHERE EXISTS ( SELECT NULL
               FROM Constellations c
               INNER JOIN ConstellationLookup cl
               WHERE c.set IN (s1,s2)
               and cl.ObjectID = o.ObjectID)

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

...