Медленные запросы в базе данных Azure - PullRequest
0 голосов
/ 18 февраля 2020

У меня 1,2 миллиона строк в таблице данных Azure. Следующая команда:

DELETE FROM _PPL_DETAIL WHERE RunId <> 229 

мучительно медленная. Есть индекс на RunId. Я удаляю большую часть данных. 229 - небольшое количество записей. Он работает уже час. Должно ли это занять много времени? Я почти уверен, что это закончится sh. Могу ли я что-нибудь сделать для ускорения подобных операций? В базе данных есть PK, хотя это фиктивный PK (не используется). Я уже видел, что оптимизация должна помочь решить эту проблему, но она все еще занимает слишком много времени (SQL Сервер обрабатывает таблицу без ПК по-другому - гораздо менее эффективно). Это все еще занимает 1 час.

Ответы [ 3 ]

1 голос
/ 19 февраля 2020

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

В настоящее время скорость фиксации журнала ограничена уровнем базы данных. Удаление в основном ограничено возможностью записывать записи журнала (и копировать их на несколько машин в случае смерти вашей основной машины). Когда вы выбираете записи, вам не нужно go по сети на N машин, и вам даже может не потребоваться go на локальный диск, если записи сохраняются в памяти, поэтому, как правило, выбор будет быстрее чем вставляет / обновляет / удаляет из-за необходимости укрепить журнал для вас. Вы можете прочитать об указанных c лимитах для разных размеров резервирования здесь: DTU Limits и vCore Limits .

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

  • Блокировка - если у вас есть другие пользователи, выполняющие операции с таблицей, это может заблокировать выполнение оператора удаления. Вы можете убедиться в этом, посмотрев sys.dm_exec_requests, чтобы увидеть, блокирует ли ваш оператор другие блокировки.
  • Выбор плана запроса. Если вам нужно отсканировать много строк, чтобы удалить небольшую часть, вы можете быть заблокированы в IO, чтобы найти их. Здесь поможет анализ формы плана запроса, так как будет установлено время статистики (мы предлагаем изменить запрос на ТОП 100 или аналогичный, чтобы понять, выполняете ли вы много логических операций чтения IOs по сравнению с реальными логическими операциями записи ). Это может означать, что ваш макет на диске не оптимален для этой проблемы. Общим решением будет либо выбрать лучшую стратегию индексирования, либо использовать секционирование, чтобы помочь вам быстро отбрасывать группы строк вместо того, чтобы явно удалять все строки.

Дополнительная стратегия для повышения производительности при удалении - дозирование .

1 голос
/ 18 февраля 2020

Как насчет попробовать что-то вроде ниже

BEGIN TRAN
SELECT * INTO #T FROM _PPL_DETAIL WHERE RunId = 229 
TRUNCATE TABLE _PPL_DETAIL
INSERT INTO _PPL_DETAIL
SELECT * FROM #T
COMMIT TRAN
0 голосов
/ 18 февраля 2020

Как я знаю SQL На сервере произошли изменения, и DOP по умолчанию равен 1 на их серверах, поэтому, если вы выполните запрос с OPTION(MAXDOP 0), это может помочь.

Попробуйте это:

DELETE FROM _PPL_DETAIL
WHERE RunId <> 229
OPTION (MAXDOP 0);
...