В настоящей статье описывается процесс параллельного выполнения операций над базой данных Microsoft SQL Server с использованием инструментария Powershell. Наиболее часто используемый сценарий - обслуживание таблиц в базе, но возможно исполнение любых запросов в параллельном режиме. Если для вас это интересно, то: Добро пожаловать. Я системный администратор "общего профиля", и помимо всего прочего - занимаюсь поддержкой Microsoft SQL Server и других систем, использующих его в своей работе. Периодически возникает необходимость в выполнении регламентных процедур на базах данных SQL Server - дефрагментация, перестроение индексов, другие операции на таблицах и индексах. Обычно эти операции выполняются через штатный функционал "Maintenance Plans", "Jobs" для SQL Server Agent, и так далее. Эти способы вполне хороши и достаточно просты для использования, но обладают общим недостатком, или особенностью: все запланированные операции в рамках одной базы данных выполняются на объектах в ней строго последовательно. Чаще всего это не критично, и можно спланировать такие операции во время регламентного окна, низкой нагрузки на сервер (ночью), и т.п. Но в зависимости от типа операций и размера обрабатываемых данных возможна ситуация, когда время выполнения таких "последовательных" операций превышает допустимое, и нужно как-то выходить из ситуации. Решение: выполнить операции параллельно сразу для нескольких таблиц/индексов в рамках одной базы. Это кратно сократит время выполнения ценой увеличения загрузки сервера. При этом далее предполагается, что у нас есть короткое регламентное окно, когда мы можем использовать всю (или большую часть) производительности сервера баз данных для своих целей, без учёта потребностей пользователей. Если у вас сервер SQL значительно нагружен в режиме 24/7 - вам нужно другое решение. Я не нашёл доступного простого решения по распараллеливанию массива запросов к базе данных, и как сисадмин - соорудил свой велосипед на базе Powershell. Если кто-то подскажет другой вариант - ссылки и ваш опыт в комментариях приветствуется. Общее описание предлагаемой схемы: Первый запрос к БД получает список таблиц/индексов/<что_вам_нужно> в ней по нужным вам критериям. Из полученного списка формируется массив запросов на T-SQL (один элемент массива для каждой таблицы/индекса), и этот массив запросов прогоняется через БД параллельно. При этом можно задать количество потоков выполнения: например массив из 100 элементов (запросы для 100 таблиц) выполнять в 10 потоков. Оптимальное количество потоков определяется экспериментально, исходя из создаваемой ими нагрузки на сервер. Здесь и далее предполагается, что читатель имеет базовые навыки администрирования ОС Windows, SQL Server и знает, что такое Powershell. Поехали...Для работы предлагаемого скрипта нам понадобится Powershell версии 7 или выше. В этой версии появилась поддержка нужногой функционала: параметр -Parallel для командлета ForEach-Object. Обратите внимание, что эта версия PoSh уже не поставляется в составе ОС Windows, и вам нужно скачать и установить её отдельно. Так же эта версия PoSh имеет свой шелл и бинарник для запуска: учитывайте это в работе.Для отладки скриптов PoSh 7.x вам возможно понадобится VS Code, но рассмотрение его установки и настройки - уже за рамками этой статьи. Параллельное выполнение запросов реализовано через вызов универсальной функции Invoke-SQLRequest за авторством вашего покорного слуги, код функции - под спойлером.   Пояснения по работе с функцией: сервер SQL и имя базы данных задаются через параметры -SqlServer и -SqlDB соответственно; поддерживается авторизация для доступа к серверу SQL как Integrated Security (от имени учётной записи, под которой выполняется скрипт), так и с указанием логина и пароля. Если -Login или -Password не заданы (пустые значения), то скрипт делает попытку авторизации на сервере SQL с использованием Integrated Security; количество потоков выполнения запросов задаётся ключом -ParallelLimit, по умолчанию - 1 поток; запрос или массив запросов к БД задаётся ключом -SQLRequest. Поддерживается (и рекомендуется) использовать массив PoSh @(), где каждый элемент - отдельный запрос; помимо собственно результата выполнения запроса, полученного от SQL Server, функция возвращает в свойстве (Property) InfoMessage дополнительную информацию: сообщение об ошибке, служебную информацию и т.д. Примеры и пояснения есть в синапсисе функции, поддерживается справочная подсистема PoSh, все важные замечания приведены в комментариях на русском языке. Т.к. выше у нас только функция, то нам понадобится дополнительный функционал для её вызова с нужными параметрами и обработки возвращаемых функцией результатов.Далее пример рабочего скрипта, реализующего полезный функционал: перестроение индексов со степенью фрагментации более заданного порога. Можно использовать его как заготовку для ваших целей. Внимание! Многопоточное перестроение индексов может загрузить ваш сервер баз данных на 100% и вызвать другие неожиданные последствия, я предупредил! Всегда тестируйте незнакомый код в тестовой среде.  Пояснения по работе со скриптом: сервер SQL и имя базы данных задаются через параметры -SqlServer и -SqlDBs соответственно. Можно указать несколько баз данных в виде массива PoSh @(), например: -SqlDBs 'DBName1','DBName2','DBName3' ; поддерживается авторизация для доступа к серверу SQL как Integrated Security (от имени учётной записи, под которой выполняется скрипт), так и с указанием логина и пароля. Если -Login или -Password не заданы (пустые значения), то скрипт делает попытку авторизации на сервере SQL с использованием Integrated Security; количество потоков выполнения запросов задаётся ключом -ParallelLimit, по умолчанию - 4 потока. Т.е. в данном случае у вас будет выполняется перестроение 4 индексов одновременно; в случае необходимости получить дополнительную служебную информацию (ошибки, статус  и т.п.), возвращаемую SQL Server вместе с результатом, можно через свойство (Property) InfoMessage возвращаемого значения.  для корректной работы скрипта в одной папке с ним предполагается наличие функции function_Invoke-SQLRequest.ps1, описанной выше. Таким образом мы получили гибкую систему для параллельного выполнения операций на объектах в базе данных с возможностью максимальной утилизации ресурсов сервера SQL. Задачи можно выполнять с любого доступного сервера, через планировщик задач или другие средства автоматизации, доработать под свои нужды и так далее: всё в ваших руках. Конкретно в моём случае применение этих скриптов позволило ускорить выполнение нужных операций над базой данных в 6(!) раз и с запасом уложиться в отведённое окно. В процессе разработки и отладки скрипта ни один сервер SQL не пострадал, но под конец я точно видел лёгкий дымок от процессора. Или не от процессора, но туман точно был :-) Спасибо за внимание, конструктивные комментарии приветствуются. Парсер на Хабре для PoSh далёк от идеала, по этому для комфортного восприятия с нормальной подсветкой копируйте код в ISE, VS Code или другой ваш любимый редактор. С прошедшим днём сисадмина, коллеги!