Пакетный запрос занимает от нескольких миллисекунд до 2 минут на SQL Server.

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

Это очень большая партия, в ней используется несколько временных таблиц,

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

В Oracle 10g пакет выполняется без проблем.

На SQLServer 2008 R2 я испытываю некоторые случайные зависания при 2-3 запросах INSERT в транзакции. Это происходит не всегда, или, может быть, это происходит с запросом (который обычно выполняется за несколько миллисекунд), но не с другим, с которым это произошло раньше.

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

Я также указываю, что все запросы выполняются только с параметром ROWLOCK.

Мониторинг SQL Server профайлером и монитором активности не вижу ничего странного.
ЦП не завис, память есть, чтение на диск около 0, запись на диск 0-200 кб/с не постоянная.

Никто другой не использует эту схему БД.

Я действительно не могу понять, как это решить.

ИЗМЕНИТЬ:

Это один из загадочных запросов

INSERT INTO "LOAD"."META_CELLS_UOM" WITH (ROWLOCK) 
("UDA_DOMAIN_ID", "META_DOC_ID", "META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_UROW", "META_CELL_UCOL", "CEM_ID") 

  SELECT "UDA_DOMAIN_ID", "META_DOC_ID", "META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_UROW", "META_CELL_UCOL", "CEM_ID"
   FROM ( 
     SELECT "META_DOCUMENTS"."UDA_DOMAIN_ID", "META_DOCUMENTS"."META_DOC_ID", "META_SECTIONS"."META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_ROW" AS "META_CELL_UROW", "META_CELL_COL" AS "META_CELL_UCOL", "CEM_ID"
     FROM "LOAD"."LOADER_CELLS_STEP_1"
     INNER JOIN "LOAD"."META_DOCUMENTS" ON ("META_DOCUMENTS"."META_DOC_CODE"="LOADER_CELLS_STEP_1"."META_DOC_CODE")
     INNER JOIN "LOAD"."META_SECTIONS" ON ("META_SECTIONS"."META_DOC_ID"="META_DOCUMENTS"."META_DOC_ID") AND ("META_SECTIONS"."META_SECT_NAME"="LOADER_CELLS_STEP_1"."META_SECT_NAME")
     INNER JOIN "LOAD"."META_SETS" ON ("META_SETS"."META_SECT_ID"="META_SECTIONS"."META_SECT_ID") AND ("META_SETS"."META_DOC_ID"="META_DOCUMENTS"."META_DOC_ID") AND ("META_SETS"."META_SET_NAME"="LOADER_CELLS_STEP_1"."META_SET_NAME")
     INNER JOIN "LOAD"."USER_DEF_ATTRIBUTES" ON ("USER_DEF_ATTRIBUTES"."UDA_NAME"="LOADER_CELLS_STEP_1"."UDA_NAME")
     WHERE ("META_CELL_WUOM"=1)
     AND ("UDA_TYPE"='MATCH')
   ) "SELECTION"
  WHERE NOT EXISTS ( 
     SELECT *
     FROM "LOAD"."META_CELLS_UOM"
     WHERE ("SELECTION"."META_SET_ID"="META_CELLS_UOM"."META_SET_ID")
     AND ("SELECTION"."UDA_ID"="META_CELLS_UOM"."UDA_ID")
  )

Целевая таблица META_CELLS_UOM пуста, исходная таблица LOADER_CELLS_STEP_1 содержит около 80 000 записей, из которых я выбираю около 3000.

ИЗМЕНИТЬ 2:

Непрерывных запросов нет. Когда программа зависает при выполнении вышеуказанного запроса, это снимок экрана монитора активности SQL Server Mngmt Studio:

введите здесь описание изображения


person Teejay    schedule 13.12.2013    source источник
comment
@SQLhint.com См. редактирование   -  person Teejay    schedule 13.12.2013
comment
Откуда вы знаете, что есть случайные блокировки? Запускаете ли вы какие-либо другие процессы в то же время? Это не может быть взаимоблокировка, так как взаимоблокировка разрешается немедленно путем уничтожения одного из процессов.   -  person Szymon    schedule 13.12.2013
comment
@Szymon Я знаю, что они случайны, потому что они не всегда зависают на одном и том же запросе, а иногда вообще не зависают. Никакие другие процессы не выполняются в этой схеме.   -  person Teejay    schedule 13.12.2013
comment
Но как узнать, что это на самом деле замки? Проверяли ли вы блокировки во время выполнения запроса? Или заблокированные процессы?   -  person Szymon    schedule 13.12.2013
comment
Извините, под блокировкой я подразумеваю запрос заблокирован на долгое время. Профилировщик SQL не наблюдает ни блокировки БД, ни взаимоблокировки БД. Также монитор активности SQL Server Management Studio показывает этот процесс как RUNNING.   -  person Teejay    schedule 13.12.2013
comment
Мне неясно: какие запросы выполняются, выполняются ли они одновременно на нескольких соединениях, информация о блокировке/блокировке, план(ы) выполнения. Нам нужно гораздо больше информации, чтобы ответить, потому что явного недостатка не видно. Никакой полезный ответ не может быть дан без дополнительной информации.   -  person usr    schedule 13.12.2013
comment
@usr Я добавил кое-какую информацию, смотрите редактирование. К сожалению, я не знаю никакой другой информации, если бы я знал, я бы, вероятно, не был на SO.   -  person Teejay    schedule 13.12.2013
comment
@usr Пожалуйста, дайте мне знать, если вы хотите, чтобы я выполнил какую-то конкретную команду для сбора дополнительной информации.   -  person Teejay    schedule 13.12.2013
comment
Хорошо, никаких одновременных запросов и, по-видимому, никакой активности на каком-либо ресурсе. Нет блокировки. Правильный? Я не знаю ни одной нормальной причины, по которой это могло бы быть. Я могу думать только об ошибке диска (зависший диск). Или какой-то другой процесс на том же сервере может перегружать диск. Но в этом случае должна быть видна информация об ожидании. Может попробовать заглянуть в журнал ошибок? Также запустите DBCC CHECKDB.   -  person usr    schedule 13.12.2013
comment
Это действительно похоже на какое-то состояние гонки. Даже если вы используете блокировки строк, вставка может (возможно) вызвать разделение таблицы, а это может привести к блокировке страниц. Попробуйте понюхать, что блокируется с помощью sp_lock2.   -  person jean    schedule 13.12.2013
comment
@usr Я тоже думал про висящий диск, попробую на ВМ. CHECKDB обнаружил 0 ошибок распределения и 0 ошибок согласованности в базе данных LOAD, то же самое для MASTER. Как посмотреть журнал ошибок?   -  person Teejay    schedule 13.12.2013
comment
@jean Sql profiler не наблюдает никаких блокировок во время пакетной обработки...   -  person Teejay    schedule 13.12.2013
comment
@Teejay в SSMS, Управление -> Журналы SQL Server. Ищите все ошибки, особенно ошибки ввода-вывода или что-либо, указывающее на зависание.; Есть ли способ воспроизвести зависание? Возможно, выполнив запрос 1000 раз?   -  person usr    schedule 13.12.2013
comment
@usr Ничего интересного в логах не нашел. Ошибок вообще нет.   -  person Teejay    schedule 13.12.2013
comment
@usr Чтобы воспроизвести зависание, мне нужно выполнить весь пакет, потому что он опирается на временные таблицы, созданные самим пакетом. При выполнении батча имею примерно 50% вероятность наблюдения зависания.   -  person Teejay    schedule 13.12.2013
comment
@jean Используя sp_lock2, я получил очень большую таблицу блокировок. Задействовано более 80 000 объектов, поэтому сложно найти какую-то важную информацию. Предложения?   -  person Teejay    schedule 13.12.2013
comment
@usr в журнале я нашел некоторые из этих строк: Autogrow of file 'LOAD_log' in database 'LOAD' took 116625 milliseconds. Consider using ALTER DATABASE to set a smaller FILEGROWTH for this file.. Может ли это быть связано с зависанием?   -  person Teejay    schedule 13.12.2013
comment
@Teejay Я ожидаю, что автоувеличение будет отображаться как тип ожидания, но, возможно, я ошибаюсь. Отключите автоматическое сжатие и отключите все задания на сжатие. Задайте размер файлов данных и журналов, чтобы в них было достаточно места для вашей транзакции (в целях тестирования увеличьте их до огромного размера). Узнайте, страдаете ли вы от фрагментации журнала, и устраните ее (simple-talk.com/sql/database-administration/). Затем посмотрите, исчезла ли проблема. Автоувеличение может вызвать скачки нагрузки и ожидания. Мы не хотим, чтобы автоматическое увеличение запускалось в производственной среде.   -  person usr    schedule 13.12.2013
comment
@usr В настоящее время я стер журнал, установив простой режим восстановления, а затем сжав БД (эй, это тестовая БД!). Смотрите, что происходит!   -  person Teejay    schedule 13.12.2013
comment
@usr Ни в коем случае, зависание остается   -  person Teejay    schedule 13.12.2013
comment
Не уменьшайте БД, увеличивайте ее! База данных с проблемой находится на виртуальной машине?   -  person Nick.McDermaid    schedule 16.12.2013
comment
Пакетный процесс для модов отличается от пакетного SQL. Пакетная обработка не является правильным тегом!   -  person Teejay    schedule 17.12.2013
comment
Эр. У вас есть событие автоматического увеличения журнала, которое занимает 116 секунд, и вы спрашиваете, почему вы получаете 120-секундную задержку? Он будет заблокирован, пока журнал растет.   -  person Martin Smith    schedule 02.01.2014
comment
@MartinSmith Нет, на самом деле это происходит, даже если бревно не растет.   -  person Teejay    schedule 07.01.2014


Ответы (1)


Не заглядывая в план выполнения, я думаю, что причина того, что запрос иногда занимает больше времени, заключается в том, что SQL-сервер пытается сократить некоторые углы, используя статистику из последнего запроса, но это имеет неприятные последствия.

Я бы сказал, что это должно быть решено, если вы

  1. Сначала выберите 3000 строк LOADER_CELLS_STEP_1 в подзапросе и присоединитесь к другим данным, иначе сервер может счесть какую-то другую таблицу лучше, а затем присоединиться ко всем 80000 строк, а затем отфильтровать их.
  2. Пропустите предложение «не существует» и напишите его по-другому, например, левое внешнее соединение с META_CELLS_UOM, и включите только несоответствующие строки. А также здесь сделайте это как отдельный подзапрос, чтобы избежать плохой оптимизации.

Try this (I dont know if I understand the relations right) and i might have missed a few tings, but I hope you understand.

INSERT INTO "LOAD"."META_CELLS_UOM" WITH (ROWLOCK) 
("UDA_DOMAIN_ID", "META_DOC_ID", "META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_UROW", "META_CELL_UCOL", "CEM_ID") 

ВЫБЕРИТЕ "UDA_DOMAIN_ID", "META_DOC_ID", "META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_UROW", "META_CELL_UCOL", "CEM_ID" ИЗ ( ВЫБЕРИТЕ "META_DOCUMENTS"."UDA_DOMAIN_ID", "META_DOCUMENTS"."META_DOC_ID" , "META_SECTIONS"."META_SECT_ID", "META_SET_ID", "UDA_ID", "META_CELL_ROW" AS "META_CELL_UROW", "META_CELL_COL" AS "META_CELL_UCOL", "CEM_ID" FROM ( выберите * из "LOAD"."LOADER_CELLS_STEP_1", где ( "META_CELL_WUOM"=1) И ("UDA_TYPE"='MATCH') ) ВНУТРЕННЕЕ СОЕДИНЕНИЕ LCS "LOAD"."META_DOCUMENTS" ON ("META_DOCUMENTS"."META_DOC_CODE"=LCS."META_DOC_CODE") ВНУТРЕННЕЕ СОЕДИНЕНИЕ "LOAD"." META_SECTIONS" ON ("META_SECTIONS"."META_DOC_ID"="META_DOCUMENTS"."META_DOC_ID") И ("META_SECTIONS"."META_SECT_NAME"=LCS."META_SECT_NAME") ВНУТРЕННЕЕ СОЕДИНЕНИЕ "LOAD"."META_SETS" ON ("META_SETS" "."META_SECT_ID"="META_SECTIONS"."META_SECT_ID") И ("META_SETS"."META_DOC_ID"="META_DOCUMENTS"."META_DOC_ID") И ("META_SETS"."META_SET_NAME"=LCS."META_SET_NAME")

) "SELECTION" оставил внешнее соединение "LOAD"."META_CELLS_UOM" включенным ("SELECTION"."META_SET_ID"="META_CELLS_UOM"."META_SET_ID") И ("SELECTION"."UDA_ID"="META_CELLS_UOM"."UDA_ID") где "META_CELLS_UOM"."META_SET_ID" равно нулю)

person Daniel Svalefelt    schedule 01.01.2014
comment
Спасибо, попробую. Извините за поздний ответ, но я был в отпуске. - person Teejay; 07.01.2014