Запрос, подобный приведенному ниже, который гарантированно не возвращает никаких строк, занимает от 0 до 160 секунд на одном из наших серверов:
select col1, col2, col3
from tab1
where 0 = 1
Две недели назад это происходило шесть раз с интервалом в 48 часов. На прошлой неделе тот же запрос занял ~ 0 секунд. У меня есть журналы SQL нашего приложения, но я еще не нашел подозреваемых. Кроме того, я подумал, что запрос типа top 0 /, где 0 = 1, никогда не попадает на страницы данных, поэтому он должен быть устойчивым к блокировкам данных на уровне строк / страниц / таблиц? Схема не затрагивается никакими (известными) SQL.
Так как проблема непоследовательна, а сервер находится под очень большой нагрузкой, я хотел бы понять теорию, лежащую в основе того, что происходит, прежде чем подключать SQL Profiler. Другие запросы выполняются без проблем во время этих задержек. Известной проблемой в приложении является большое количество динамически создаваемых SQL-запросов - около 200 тыс. Уникальных запросов из 850 тыс. Запросов в течение 48 часов. Может ли это вызвать такие проблемы?
На сервере установлена стандартная версия SQL Server 2005, 96 ГБ ОЗУ, диски в сети SAN и 4 процессора / 16 ядер. Файлы базы данных и файловые группы хорошо оптимизированы и не должны быть проблемой (но мы рассматриваем это отдельно).
Любые указатели, где искать, с благодарностью.
Редактировать: Отлично! Повторил запрос, чтобы добавить план выполнения, и потребовалось 1 минута 35 секунд. Вот план выполнения и скриншот, показывающий продолжительность запроса:
Редактировать 2: статистика времени детали для второго запуска. Кажется, сейчас все идет медленно, поэтому мы добавим профилировщик и perfmon:
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 97402 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
источник
Ответы:
Похоже, что даже с
... WHERE 0 = 1
условием, что по-прежнему будет требоваться намереннаяIS
блокировка shared ( ) для таблицы. Давайте докажем это:Я начну с создания тестовой таблицы:
Теперь, когда у меня есть тестовая таблица, в одном сеансе (окно запроса) я собираюсь выполнить следующее, чтобы установить
X
блокировку exclusive ( )dbo.MyTestTable1
:Я могу проверить эксклюзивную блокировку, посмотрев на
sys.dm_tran_locks
DMV. Затем в другом сеансе (новое окно запроса) я делаю именно то, что делает ваш запрос:На первый взгляд я вижу, что это не завершает. Глядя на это
sys.dm_exec_requests
, я точно понимаю, почему это так:Я вижу здесь, что мой
... WHERE 0 = 1
запрос ожидаетIS
блокировки для этого объекта (что object_id переводит вdbo.MyTestTable1
).Я ни в коем случае не говорю, что параллелизм - это ваша проблема, но, судя по звукам, вы проявляете симптомы. Приведенный выше пример должен доказать, что вы не освобождаетесь от блокировки и блокировки даже с помощью
WHERE
предложения, которое никогда не вернет данные.Все, что мы можем сделать, это угадать, поэтому, что вам нужно сделать, когда это «занимает много времени», - это увидеть, что именно делает этот запрос, который занимает так много времени. Если он чего-то ждет, то посмотри, чего он ждет.
источник
В зависимости от того, насколько резкими и требовательными являются ваши запросы, ваша система может просто поставить этот запрос в очередь. Число рабочих по умолчанию (т.е. число одновременных потоков SQL-сервера) для вашей установки должно быть около 700.
Проверьте sys.dm_os_schedulers и sys.dm_os_waiting_tasks, чтобы увидеть, может ли это быть проблемой.
источник