Начать хранимые процедуры последовательно или параллельно

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

  • Как я могу указать SQL Server, следует ли запускать процедуру параллельно или по серийному номеру; т.е.: начался асинхронный или блокирующий?
  • Каковы были бы последствия для их параллелизма, имея в виду, что я уже определил, что процессы не будут конкурировать за доступ к таблицам или блокировки - просто общий объем диска и память. По большей части они даже не используют одни и те же таблицы.
  • Имеет ли значение, если некоторые из этих процедур являются одной и той же процедурой, только с разными параметрами?
  • Если я запускаю пару или процедуры асинхронно, есть ли хорошая система в SQL Server, чтобы дождаться, когда они закончатся, или мне нужно, чтобы каждый из них установил флаг где-нибудь, и периодически проверяйте и опросите флаг используя WAITFOR DELAY?

В настоящий момент мы все еще находимся на SQL Server 2000.

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

Ответ 1

Мне пришлось исследовать это недавно, поэтому нашел этот старый вопрос, который попросил дать более полный ответ. Просто чтобы быть полностью явным: TSQL не (сам по себе) имеют возможность запускать другие операции TSQL асинхронно.

Это не значит, что у вас еще не так много вариантов (некоторые из них упомянуты в других ответах):

  • Пользовательское приложение. Напиши простое пользовательское приложение на выбранном вами языке, используя асинхронные методы. Вызовите SQL-хранимый proc для каждого потока приложений.
  • Задания SQL-агента. Создайте несколько заданий SQL и запустите их асинхронно из вашего proc с помощью sp_start_job. Вы можете проверить, закончили ли они все еще, используя недокументированную функцию xp_sqlagent_enum_jobs, как описано в этой замечательной статье Грегори А. Ларсена. (Или сами задания сами обновляют вашу собственную таблицу JOB_PROGRESS, как предлагает Крис.) Вам буквально пришлось бы создавать отдельное задание для каждого параллельного процесса, который вы ожидаете, даже если они работают с тем же хранимым процессом с разными параметрами.
  • Автоматизация OLE. Используйте sp_oacreate и sp_oamethod для запуска нового процесса, вызывающего другой сохраненный процесс, как описано в this статья, также Григорий А. Ларсен.
  • Пакет DTS. Создайте пакет DTS или SSIS с простым потоком задач ветвления. DTS запускает задачи в отдельных штифтах.
  • Service Broker. Если вы используете SQL2005 +, используйте Service Broker
  • Параллельное выполнение CLR. Используйте команды CLR Parallel_AddSql и Parallel_Execute, как описано в в этой статье Алан Каплан (только для SQL2005 +).
  • Запланированные задачи Windows: список полноты, но я не поклонник этой опции.

У меня нет большого опыта работы с Service Broker или CLR, поэтому я не могу комментировать эти параметры. Если бы это был я, я бы, вероятно, использовал несколько Джобсов в более простых сценариях и пакет DTS/SSIS в более сложных сценариях.

Один заключительный комментарий: SQL уже пытается распараллелить отдельные операции, когда это возможно *. Это означает, что выполнение двух задач одновременно, а не друг за другом, не гарантирует, что он закончит раньше. Тщательно проверяйте, действительно ли это что-то улучшает или нет.

У нас был разработчик, который создал пакет DTS для одновременного запуска 8 задач. К сожалению, это был только 4-процессорный сервер:)

* Предполагая настройки по умолчанию. Это можно изменить, изменив максимальную степень сервера Parallelism или маску близости или с помощью подсказки запроса MAXDOP.

Ответ 2

Создайте несколько заданий агента SQL Server, где каждый из них запускает определенный процесс.

Затем из вашего мастер-процесса откройте задания.

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

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

Последствия памяти полностью соответствуют вашей среде.

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

UPDATE2: Кроме того, если вы хотите создать новое приложение, вы можете разместить всю логику в одном exe...

Ответ 3

Вам нужно переместить ночные sprocs на работу. Управление заданиями SQL Server позволит вам выполнить все расписания, о которых вы просите.

Ответ 4

Возможно, вы захотите изучить использование DTS (которое может быть запущено из SQL-агента как задание). Это позволит вам довольно тонко контролировать, какие хранимые процедуры должны ждать, пока другие не закончатся, и что может работать параллельно. Вы также можете запустить пакет DTS в качестве EXE из своего собственного программного обеспечения для планирования, если это необходимо.

ПРИМЕЧАНИЕ. Вам нужно будет создать несколько копий ваших объектов соединения, чтобы разрешить запуск вызовов параллельно. Два вызова с использованием одного и того же объекта соединения будут по-прежнему блокировать друг друга, даже если вы явно не входите в зависимость.