Начать хранимые процедуры последовательно или параллельно
У нас есть хранимая процедура, которая выполняется ночью, что, в свою очередь, запускает ряд других процедур. Некоторые из этих процедур могут логически выполняться параллельно с некоторыми другими.
- Как я могу указать 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 из своего собственного программного обеспечения для планирования, если это необходимо.
ПРИМЕЧАНИЕ. Вам нужно будет создать несколько копий ваших объектов соединения, чтобы разрешить запуск вызовов параллельно. Два вызова с использованием одного и того же объекта соединения будут по-прежнему блокировать друг друга, даже если вы явно не входите в зависимость.