Любая хранимая процедура множественных записей SQL Server получила? - PullRequest
7 голосов
/ 23 января 2009

Контекст

Мой текущий проект - это большой публичный сайт (2 миллиона просмотров страниц в день), на котором работает смесь asp classic и asp.net с серверной частью SQL Server 2005. Мы много читаем, иногда записываем и практически не обновляем / удаляем. Наши страницы обычно относятся к одному «главному» объекту со стеком зависимых (подробных) объектов.

Мне нравится идея вернуть все данные, необходимые для страницы, в одном процессе (и абсолютно никаких ненужных данных). Правда, для таких страниц требуется отдельная процедура, но некоторые страницы получают двузначные проценты от общего трафика нашего сайта, поэтому стоит потратить время на обслуживание. Обычно мы используем только несколько наборов записей из нашего кода .net, используя System.Data.SqlClient.SqlDataReader и его метод NextResult. О да, я не делаю никаких обновлений / вставок в этих процессах (кроме табличных переменных).

Вопрос

Процессы SQL Server (2005), которые возвращают несколько наборов записей, работают для нас хорошо (в prod) до сих пор, но меня немного беспокоит то, что процессоры с несколькими наборами записей - мой новый любимый молоток, который решает все проблемы с. Есть ли какие-нибудь многосерийные наборы SQL Server, о которых я должен знать? Что-нибудь, что заставит меня хотеть, чтобы я не использовал их? В частности, все, что связано с пулом соединений, использованием памяти и т. Д.

Ответы [ 3 ]

7 голосов
/ 23 января 2009

Вот несколько ошибок для хранимых процедур с несколькими наборами записей:

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

Они усложняют юнит-тестирование. Каждый раз, когда вы вносите изменения в один из запросов, вам необходимо протестировать все результаты. Если что-то изменилось, вам нужно разобраться, какой запрос не прошел модульный тест.

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

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

Они могут увеличить проблемы с блокировкой и вызвать загрузку в TempDB. Если ваши хранимые процессы разработаны так, что требуют повторяющихся чтений, то чем больше запросов вы добавляете в хранимый процесс, тем дольше он собирается выполнить, и чем больше времени потребуется, чтобы вернуть эти результаты обратно на сервер приложений. Это увеличенное время означает более высокий уровень конкуренции за блокировки, и тем больше SQL Server нужно хранить в TempDB для контроля версий строк. Вы упомянули, что у вас много чтения, поэтому эта конкретная проблема не должна быть для вас слишком серьезной, но вы должны знать об этом, прежде чем использовать этот молот в приложении с интенсивной записью.

4 голосов
/ 23 января 2009

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

Чем больше (больше трафика) вашего сайта, тем важнее будет то, что «дополнительная» производительность будет иметь значение. Если вы можете объединить 2-3-4 звонка (и, возможно, новые соединения), к базе данных в один, вы можете сократить количество обращений к вашей базе данных на 4-6-8 миллионов в день, что существенно.

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

2 голосов
/ 23 января 2009

Я бы рекомендовал вызывать в одной хранимой процедуре несколько внутренних вызовов хранимых процедур, каждый из которых возвращает 1 набор результатов.

create proc foo 
as
execute foobar --returns one result

execute barfoo --returns one result

execute bar  --returns one result

Таким образом, когда требования изменяются и вам нужен только 3-й и 5-й набор результатов, у вас есть простой способ вызвать их без добавления новых хранимых процедур и восстановления слоя доступа к данным. Мое текущее приложение возвращает все справочные таблицы (например, таблицу штатов США), если я хочу их или нет. Хуже всего, когда вам нужно получить справочную таблицу, и единственный доступ осуществляется через хранимую процедуру, которая также выполняет дорогой запрос как один из шести наборов результатов.

...