В вызовах синхронизации запросов один запрос вызывает замедление работы другого запроса. Зачем? - PullRequest
0 голосов
/ 16 мая 2010

Извините за длинный вопрос, но я думаю, что это интересная ситуация, и я не смог найти объяснения этому:

Я занимался оптимизацией приложения, которое выполняло большое количество последовательных операторов SELECT и INSERT в одной выделенной базе данных SQL Server.

Процесс должен ВСТАВИТЬ большое количество записей в таблицу, но для каждой из них должно быть несколько отображений значений, которые выполняются с использованием операторов SELECT для другой таблицы в той же базе данных. Для конкретного выполнения потребовалось 90 минут.

Я использовал профилировщик (JProfiler - приложение основано на Java), чтобы определить, сколько времени занимает каждая часть приложения. Это дает 60% времени, потраченного на вызовы метода INSERT, и почти 20% времени на вызовы SELECT (остальное распределено в других частях).

После некоторых испытаний я пришел к такой ситуации: я закомментировал запрос INSERT, который занимал 60% времени. Я ожидал, что общее время выполнения составит около 35 минут, так как я удалил 60% из 90 минут. Но весь процесс занял те же 90 минут (только SELECT и ничего больше), но каждый SELECT занимал больше времени!

Все работало с синхронизацией, асинхронных вызовов не было. И был только один поток исполнения. Запросы SELECT и INSERT очень просты и не имеют ничего особенного, они находятся в разных таблицах, но в одной и той же БД.

Я тестировал как БД на компьютере приложения, так и на удаленном сетевом компьютере.

Я не могу придумать какого-либо объяснения этому, поскольку Profiler (Профилировщик приложений, а не SQL Profiler) сообщил об изменениях во времени вызова метода, и, удалив операторы INSERT, инструкции SELECT потребовали больше времени для запуска.

Кто-нибудь может дать мне какое-то объяснение того, что могло бы произойти?

(не может быть кеширования / оптимизации запросов, потому что запросы выполнялись синхронно и в одном потоке, и это не сильно влияло на кеш)

Я должен отметить, что узким местом скорости был SQL-сервер, использующий большую часть процессорного времени.

Ответы [ 4 ]

1 голос
/ 17 мая 2010

Ваша заявка заблокирована в базе данных вызовов. Когда вы измеряли в первый раз, блокировка происходила на INSERT, потому что, возможно, это были звонки, которые блокировали первыми. Когда вы удалили INSERT, клиентский код вспахивал вперед и блокировал при следующих вызовах SELECT. Здесь нет ничего особенного, вы просто удалили один вызов, и приложение просто заблокировало следующий вызов.

Что вам действительно нужно исследовать, так это блокирование базы данных. Забудьте о клиентской стороне JProfiler и обо всем остальном. Вместо этого сосредоточьтесь на том, что происходит с базой данных, и используйте методики устранения проблем с базами данных. Вероятно, ваша проблема - конфликт, и вы блокируете блокировки.

Очевидные проблемы будут видны сразу после простого просмотра списка процессов на сервере (sys.dm_exec_requests). Более тонкие проблемы могут быть исследованы с использованием методологии Waits and Queues .

1 голос
/ 16 мая 2010

Может быть, что вставки либо:

a) статистику таблиц / индексов, на которую влияют, так что был выбран лучший план выполнения для выборок.

b) сохраненные данные, необходимые для выбора в буфере.

Может быть интересно собирать журналы perfmon для сравнения, уделяя особое внимание «Коэффициенту попадания в Buffer Manager / Buffer Cache» и «Ожидаемая продолжительность жизни страницы» наряду с обычными подозреваемыми, т. Е. ЦП, физический диск и т. Д.

Возьмите трассировку профилировщика SQL на время обоих тестов и запустите вывод через скруббер трассировки (http://msdn.microsoft.com/en-us/library/aa175800%28sql.80%29.aspx).

0 голосов
/ 16 мая 2010

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

Одна из возможностей заключается в том, что ваши ВСТАВКИ вызывают большое количество разбиений страниц. Другая причина в том, что у вас нет индексов, что приводит к поискам SELECT для сканирования таблиц.

Попробуйте перестроить индексы перед выполнением INSERTS и выясните, сколько заполняющего фактора имеют ваши индексы. Для таблиц с высокой вставкой я часто устанавливаю 75% (вместо значения по умолчанию 90%), но вам необходимо учитывать размеры строк, так как это увеличит общее количество требуемых страниц.

0 голосов
/ 16 мая 2010

Обычно подозревается высокая загрузка ЦП - отсутствие индексов. В этом случае выполнение SELECT может занять больше времени, чем раньше, поскольку у вас больше данных.

Однако без некоторых примеров SQL со схемой будет трудно сказать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...