Моя компания использует приложение, которое имеет довольно серьезные проблемы с производительностью. Есть ряд проблем с самой базой данных, над которыми я сейчас работаю, но многие проблемы связаны исключительно с приложениями.
В своем исследовании я обнаружил, что миллионы запросов попадают в базу данных SQL Server, которые запрашивают пустые таблицы. У нас есть около 300 пустых таблиц, и некоторые из этих таблиц запрашиваются до 100-200 раз в минуту. Таблицы не имеют ничего общего с нашей бизнес-сферой и по сути являются частями исходного приложения, которое поставщик не удалил, когда они заключили контракт с моей компанией на разработку программного решения для нас.
Помимо того, что мы подозреваем, что журнал ошибок нашего приложения переполнен ошибками, связанными с этой проблемой, поставщик заверяет нас, что это не повлияет на производительность или стабильность приложения или сервера базы данных. Журнал ошибок заполняется до такой степени, что мы не можем видеть ошибок более 2 минут для диагностики.
Фактическая стоимость этих запросов, очевидно, будет низкой с точки зрения циклов ЦП и т. Д. Но кто-нибудь может подсказать, как это повлияет на SQL Server и приложение? Я подозреваю, что действительная механика отправки запроса, его подтверждения, обработки, возврата и подтверждения получения приложением сама по себе влияет на производительность.
Мы используем SQL Server 2008 R2, Oracle Weblogic 11g для приложения.
@ Frisbee - Короче говоря, я создал таблицу, содержащую текст запроса, который попал в пустые таблицы в базе данных приложения, затем запросил его для всех имен таблиц, которые, как я знаю, пусты, и получил очень длинный список. Максимальный результат - 2,7 млн. Выполнений за 30 дней безотказной работы, учитывая, что приложение обычно используется с 8:00 до 18:00, поэтому эти цифры более сконцентрированы на рабочих часах. Несколько таблиц, несколько запросов, вероятно, некоторые из них связаны через объединения, некоторые нет. Главный хит (2,7 млн. В то время) был простым выбором из одной пустой таблицы с предложением where, без объединений. Я ожидал бы, что большие запросы с объединениями к пустым таблицам могут включать обновления связанных таблиц, но я проверю это и обновлю этот вопрос как можно скорее.
Обновление: существует 1000 запросов с количеством выполнений от 1043 до 4622614 (более 2,5 месяцев). Мне придется копать больше, чтобы узнать, когда происходит кэширование плана. Это просто, чтобы дать вам представление о степени запросов. Большинство из них достаточно сложны с более чем 20 объединениями.
@ srutzky- да, я думаю, что есть колонка с датой, когда план был составлен, так что это может быть интересно, поэтому я это проверю. Интересно, будут ли ограничения потоков вообще фактором, когда SQL Server находится в кластере VMware? К счастью, скоро будет выделенный Dell PE 730xD.
@ Фрисби - Извините за поздний ответ. Как вы предложили, я запустил команду select * из пустой таблицы 10000 раз в течение 24 потоков, используя SQLQueryStress (то есть фактически 240 000 итераций), и сразу же набрал 10000 Batch Requests / sec. Затем я сократил до 1000 раз по 24 потокам и набрал чуть менее 4000 запросов в секунду. Я также попробовал 10000 итераций только для 12 потоков (таким образом, всего 120000 итераций), и это дало устойчивые 6 505 пакетов / сек. Влияние на ЦП было действительно заметным, около 5-10% от общего использования ЦП во время каждого запуска тестирования. Ожидания в сети были незначительными (например, 3 мс с клиентом на моей рабочей станции), но влияние ЦП было там точно, что, на мой взгляд, довольно убедительно. Это, кажется, сводится к использованию процессора и небольшому количеству ненужного ввода-вывода файла базы данных. Общее количество выполнений в секунду составляет чуть менее 3000, это больше, чем в производстве, однако я тестирую только один из десятков подобных запросов. Таким образом, суммарный эффект сотен запросов, обрабатывающих пустые таблицы со скоростью 300-4000 раз в минуту, не будет пренебрежимо мал, когда речь идет о времени процессора. Все тесты проводились на простое PE 730xD с двумя флэш-массивами и 256 ГБ оперативной памяти, 12 современными ядрами.
@ srutzky- хорошее мышление. SQLQueryStress, кажется, использует пул соединений по умолчанию, но я все равно посмотрел и обнаружил, что да, флажок для пулов соединений установлен. Обновление, чтобы следовать
@ srutzky- Пул соединений, по-видимому, не включен в приложении - или, если он есть, он не работает. Я выполнил трассировку профилировщика и обнаружил, что соединения имеют EventSubClass «1 - Non-pooled» для событий входа в систему аудита.
RE: Connection Pooling - проверил блогологию и обнаружил, что пул соединений включен. Обнаружил больше следов от живых и обнаружил, что признаки объединения не происходят правильно / вообще:
И вот как это выглядит, когда я запускаю один запрос без соединений с заполненной таблицей; Исключения гласят: «При установлении соединения с SQL Server произошла ошибка, связанная с сетью или экземпляром. Сервер не был найден или был недоступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен для разрешения удаленных подключений. (поставщик: поставщик именованных каналов, ошибка: 40 - не удалось открыть соединение с SQL Server) «Обратите внимание на счетчик пакетных запросов. Проверка связи с сервером во время генерирования исключений приводит к успешному ответу проверки связи.
Обновление - два последовательных теста, одна и та же рабочая нагрузка (выберите * из EmptyTable), пул включен / не включен. Чуть больше загрузка процессора и много сбоев, и никогда не превышает 500 пакетных запросов / сек. Тесты показывают 10000 пакетов / сек и без сбоев при включенном пуле, и около 400 пакетов / сек, а затем много сбоев из-за отключения пула. Интересно, связаны ли эти ошибки с отсутствием доступности соединения?
@ srutzky - Выберите Count (*) из sys.dm_exec_connections;
Пул включен: 37 последовательно, даже после остановки нагрузочного теста
Пул отключен: 11-37 в зависимости от того,
возникают ли исключения в SQLQueryStress, то есть: когда эти впадины появляются в
графе «Пакеты / сек», исключения возникают в SQLQueryStress, а
количество соединений падает до 11, а затем постепенно возвращается до 37 когда партии начинают достигать максимума, а исключения не возникают. Очень, очень интересно
Максимальное количество подключений в обоих тестовых / живых экземплярах по умолчанию равно 0.
Проверьте журналы приложений и не можете найти проблемы с подключением, однако, существует всего несколько минут для ведения журнала из-за большого количества и размера ошибок, т. Е. Большого количества ошибок трассировки стека. Коллега по поддержке приложений сообщает, что возникает значительное количество ошибок HTTP, связанных с подключением. Исходя из этого, может показаться, что по какой-то причине приложение неправильно создает пулы соединений, и в результате на сервере постоянно заканчиваются соединения. Я буду смотреть в журналы приложений больше. Интересно, есть ли способ доказать это происходит в производстве со стороны SQL Server?
@ srutzky- Спасибо. Завтра я проверю конфиг weblogic и обновлю. Я думал только о 37 соединениях - если SQLQueryStress выполняет 12 потоков с 10 000 итераций = 120 000 операторов выбора без пула, разве это не значит, что каждый выбор создает отдельное соединение с экземпляром sql?
@ srutzky - Weblogics настроен на пул соединений, поэтому он должен работать нормально. Пул соединений настраивается следующим образом для каждой из 4 веб-журналов с балансировкой нагрузки:
- Начальная емкость: 10
- Максимальная вместимость: 50
- Минимальная вместимость: 5
Когда я увеличиваю количество потоков, выполняющих запрос на выборку из пустой таблицы, число соединений достигает пика около 47. При отключенном пуле соединений я постоянно вижу снижение максимального числа запросов в секунду (с 10 000 до 400). Каждый раз будет происходить то, что «исключения» в SQLQueryStress возникают вскоре после того, как пакет / сек входит в корыто. Это связано с подключением, но я не могу понять, почему именно это происходит. Когда тесты не выполняются, #connections снижается примерно до 12.
Когда пул соединений отключен, у меня возникают проблемы с пониманием, почему возникают исключения, но, может быть, это совершенно другой вопрос / вопрос для stackamchange для Адама Маханича?
@srutzky Интересно, почему исключения происходят без включения пула, даже если в SQL Server не заканчиваются соединения?
SELECT COUNT(*) FROM sys.dm_exec_connections;
чтобы увидеть, сильно ли отличается значение между включенным пулированием или не. Исходя из этих ошибок, я думаю, что было бы гораздо больше соединений, когда пул отключен.Pooling=false
илиMax Pool Size
?Ответы:
Да, и есть даже некоторые дополнительные факторы, но степень, в которой какой-либо из них действительно влияет на вашу систему, невозможно определить без анализа системы.
При этом вы спрашиваете, в чем может быть проблема, и есть некоторые вещи, которые следует упомянуть, даже если некоторые из них в настоящее время не являются фактором в вашей конкретной ситуации. Вы говорите, что:
Может быть даже больше, но это должно помочь понять смысл вещей. И имейте в виду, что, как и большинство проблем с производительностью, все зависит от масштаба. Все предметы, упомянутые выше, не являются проблемой, если их ударить раз в минуту. Это похоже на тестирование изменений на вашей рабочей станции или в базе данных разработки: оно всегда работает только с 10 - 100 строками в таблицах. Переместите этот код в рабочий процесс, и его выполнение займет 10 минут, и кто-то обязательно скажет: «Ну, он работает на моем компьютере» ;-). Это означает, что проблема возникает только из-за большого количества звонков, но такая ситуация существует.
Таким образом, даже при 1 миллионе бесполезных запросов в 0 строк это составит:
поддерживается больше соединений, которые занимают больше памяти. Сколько у вас неиспользуемой физической памяти? эта память будет лучше использоваться для выполнения запросов и / или кэша плана запросов. В худшем случае вам не хватает физической памяти, и SQL Server должен начать использовать виртуальную память (swap), поскольку это замедляет работу (проверьте журнал ошибок SQL Server, чтобы узнать, получаете ли вы сообщения о выгружаемой памяти).
И на всякий случай кто-нибудь скажет: «ну, есть пул соединений». Да, это определенно помогает уменьшить количество необходимых соединений. Но с запросами, поступающими со скоростью до 200 раз в минуту, это много одновременных действий, и для законных запросов все еще должны существовать соединения. Сделайте,
SELECT * FROM sys.dm_exec_connections;
чтобы увидеть, сколько активных соединений вы поддерживаете.Если я не ошибаюсь в том, что я здесь заявляю, то мне кажется, что, даже если в небольшом масштабе это тип DDoS-атаки на вашу систему, поскольку она наводняет сеть и ваш SQL-сервер поддельными запросами предотвращение попадания реальных запросов в SQL Server или их обработки SQL Server.
источник
Если таблицы подвергаются ударам 100-200 раз в минуту, то они (надеюсь) находятся в памяти. Нагрузка на сервер очень и очень низкая. Если у вас нет высокой загрузки ЦП или памяти на сервере базы данных, это, вероятно, не проблема.
Да, запросы принимают общие блокировки, но, надеюсь, они не блокируют какие-либо блокировки обновлений и не блокируются никакими обновлениями. Есть ли у вас какие-либо обновления, вставки или удаления на этих таблицах. Если нет, то я бы просто отпустил это - если у вас проблемы с производительностью, то с точки зрения сервера баз данных нужно больше рыбы.
Я выполнил тест на 100 000 выборочных счетчиков (*) для пустой таблицы, и он прошел за 32 секунды, и запросы были переданы по сети. Итак, 1/3 миллисекунды. Если ваша сеть не перегружена, это даже не влияет на клиента. Если у вас есть серьезные проблемы с производительностью, эти пустые запросы в 1/3 миллисекунды - это не то, что убивает приложение.
И они могут быть просто частью левого соединения, собирающего некоторые статические данные типа, которые не являются частью текущего приложения. Это может быть связано с другими запросами, так что это не дополнительная поездка туда и обратно. Если да, то это небрежно, но даже не вызывает больше трафика.
Итак, вернемся к фактическим утверждениям. Вы видите какие-либо обновления, добавления или удаления в этих таблицах?
Да, многие пустые таблицы и запросы к пустым таблицам указывают на небрежное кодирование. Но если у вас есть серьезные проблемы с производительностью, это не является причиной, если у вас нет действительно неаккуратных операций записи, также выполняющихся с этими таблицами.
источник
В целом по каждому запросу выполняются следующие шаги:
многие из упомянутых вами запросов могут вызвать дополнительную нагрузку на систему, которая уже тяжелая - дополнительная нагрузка на соединения, ЦП, ОЗУ и ввод / вывод.
источник