Моя компания использует приложение, которое имеет довольно серьезные проблемы с производительностью. Есть ряд проблем с самой базой данных, над которыми я сейчас работаю, но многие проблемы связаны исключительно с приложениями.
В своем исследовании я обнаружил, что миллионы запросов попадают в базу данных 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
?