Каковы лучшие переменные в хранимых процедурах - PullRequest
0 голосов
/ 19 ноября 2009

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

В последний раз, когда я настраивал некоторые временные таблицы, например, один с именем #tmpGlobals и другой с именем #tmpOutput. Имена не имеют значения, но я исключил использование объявления некоторого @MainID int или чего-то подобного.

Это хорошая идея? Это проблема с производительностью?

Ответы [ 3 ]

1 голос
/ 19 ноября 2009

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

Существует распространенное заблуждение, что переменные @table находятся только в памяти, не требуют ввода-вывода, не используют базу данных tempdb и т. Д. Хотя в некоторых отдельных случаях это верно, это не то, что вы можете или должны положитесь.

Некоторые другие ограничения переменных @table, которые могут помешать их использованию даже для небольших наборов данных:

  • не может индексировать (кроме объявлений первичного ключа / уникального ограничения при создании)
  • статистика не поддерживается (в отличие от #temp таблиц)
  • не может изменить
  • нельзя использовать в качестве цели INSERT EXEC в SQL Server 2005 (это ограничение было снято в 2008 году)
  • нельзя использовать в качестве цели SELECT INTO
  • не может усечь
  • не может использовать тип псевдонима в определении
  • без параллелизма
  • невидимо для вложенных процедур (в отличие от таблиц #temp)
0 голосов
/ 19 ноября 2009

В общем, вы должны выбрать обратное, если это возможно. Это зависит от того, нужно ли вам хранить набор элементов или просто значения результата.

Переменные с областью видимости, кроме табличных, относительно дешевы. Вещи, которые вписываются в типизированные переменные, которые не являются таблицами, работают быстрее, чем их хранение в виде отдельных строк в таблице.

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

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

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

Использование выражений общей таблицы @ MSDN

редактировать: (относительно временных таблиц)

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

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

0 голосов
/ 19 ноября 2009

Это действительно зависит от количества данных. Если вы используете менее 100 записей, тогда, вероятно, лучше использовать DECLARE @MainID или тому подобное, поскольку это меньший объем данных. Что-нибудь более 100 записей, тем не менее, вы обязательно должны использовать #tmpGlobals или подобное, так как это лучше для управления памятью на сервере SQL.

РЕДАКТИРОВАТЬ: Это не плохо для использования #tmpGlobals для небольших наборов, просто не большая потеря производительности или выигрыша от DECLARE @MainID. Вы увидите увеличение производительности при использовании #tmpGlobals вместо DECLARE @MainID на большом количестве записей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...