преобразование функции в хранимую процедуру

#sql

#sql

Вопрос:

Я работаю в приложении, которое имеет пользовательские функции во всех WHERE предложениях уровня данных, и я уверен, что это вызывает проблемы с производительностью.

В качестве примера предположим, что есть отчет, содержащий записи и комментарии, и есть функция

 where (dbo.CountComments(entries.id, '5/10/2011') = 0)
  

…показываем нам, скажем, записи без комментариев на сегодняшний день.

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

Если бы вам пришлось переписать это как SP, как бы вы это сделали?

Ответ №1:

Пара мыслей.

Во-первых, использование COUNT = 0 для определения того, что чего-либо нет, неэффективно. Вам лучше использовать

 NOT EXISTS (SELECT...)
  

Таким образом, SQL может отказаться, как только найдет строку, возвращающую false, вместо того, чтобы посещать их все, чтобы возвращать ненулевое количество.

Во-вторых, где вы используете эту функцию в своих запросах? Если вы хотите использовать ее выходные данные в качестве критериев запроса, как в вашем примере, вы не сможете сделать это с помощью хранимых процедур.

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

Комментарии:

1. Точно — я хочу использовать ее выходные данные в качестве критериев запроса. Спасибо, что вызвали эту формулировку, которая ускользала от меня. Просмотры — тоже хорошая идея, спасибо.

Ответ №2:

Вы могли бы попробовать использовать базовый SQL. Возможно, что-то вроде следующего:

 SELECT   *
FROM     comments c
WHERE    NOT EXISTS(SELECT commentID FROM comments c2 WHERE dateCreated >= getDate() AND c.commentID = c2.commentID)
  

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

Комментарии:

1. Нет, вы продолжаете. Однако добавление предложения «NOT EXISTS» кажется более медленным, чем функция. Тем не менее, я продолжу играть с этой идеей.

2. Вы случайно не знаете, проиндексирован ли столбец, к которому вы присоединяетесь? Если это не так, это, безусловно, также замедлит работу.

Ответ №3:

Если вы перепишете это в хранимую процедуру, вы не сможете использовать это в предложении WHERE. Только функции предоставят вам такую возможность.

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