Моя компанія використовує додаток, який має досить великі проблеми з продуктивністю. Існує ряд проблем із самою базою даних, над якими я працюю, але багато проблем пов'язані виключно із додатком.
Під час мого розслідування я виявив, що в базу даних SQL Server є мільйони запитів, які запитують порожні таблиці. У нас близько 300 порожніх таблиць, і деякі з цих таблиць запитуються до 100-200 разів на хвилину. Таблиці не мають нічого спільного з нашою діловою сферою і, по суті, є частинами оригінальної програми, яку постачальник не видаляв, коли їх компанія могла надати контракт на виробництво програмного рішення для нас.
Окрім того, що ми підозрюємо, що наш журнал помилок додатків заповнений помилками, пов’язаними з цією проблемою, постачальник запевняє нас, що не впливає на продуктивність чи стабільність ані додаток, ані сервер бази даних. Журнал помилок затоплений настільки, що ми не можемо побачити помилки, що мають більше ніж 2 хвилини для діагностики.
Фактична вартість цих запитів, очевидно, буде низькою з точки зору циклів процесора і т. Д. Але чи може хто-небудь підказати, який ефект буде мати на SQL Server та програму? Я б підозрював, що реальна механіка надсилання запиту, його підтвердження, обробки, повернення та підтвердження отримання заявкою сама по собі матиме вплив на продуктивність.
Для програми ми використовуємо SQL Server 2008 R2, Oracle Weblogic 11g.
@ Frisbee - Коротше кажучи, я створив таблицю із запитомтексту, який потрапив у порожні таблиці в базі даних програми, а потім запитав його для всіх імен таблиць, які я знаю, порожніми і отримав дуже довгий список. Найбільше враження було в 2,7 мільйонів страт за 30 днів безперервного часу, маючи на увазі, що програма, як правило, використовується 8 ранку до 18 вечора, тому ці цифри є більш сконцентрованими до робочих годин. Кілька таблиць, кілька запитів, можливо, деякі відновляться через приєднання, деякі ні. Найбільше звернення (2,7 мільйони на той час) було простим вибором з однієї порожньої таблиці з пунктом де, не приєднується. Я б очікував, що більші запити з приєднанням до порожніх таблиць можуть включати оновлення зв'язаних таблиць, але я перевірю це та скоріше оновлюю це питання.
Оновлення: Є 1000 запитів, кількість виконання - від 1043 до 4622614 (понад 2,5 місяці). Мені доведеться більше копати, щоб з’ясувати, звідки походить кешований план. Це лише для того, щоб дати уявлення про ступінь запитів. Більшість є досить складними з більш ніж 20 з'єднаннями.
@ srutzky- так, я вважаю, що стовпчик дат пов'язаний з тим, коли план був складений, щоб викликати інтерес, тому я перевірю це. Цікаво, чи не обмеження потоків буде фактором, коли SQL Server сидить на кластері VMware? Незабаром буде вдячний Dell PE 730xD на щастя.
@Frisbee - Вибачте за пізню відповідь. Як ви запропонували, я запустив вибраний * з порожньої таблиці 10 000 разів за 24 потоки за допомогою SQLQueryStress (тобто насправді 240 000 ітерацій) і негайно натиснув 10 000 пакетних запитів / сек. Потім я зменшився в 1000 разів за 24 теми і натиснув трохи менше 4 000 пакетних запитів / сек. Я також спробував 10 000 ітерацій лише на 12 потоків (тобто 120000 загальних ітерацій), і це призвело до стійких 6,505 партій / сек. Ефект на процесорі був фактично помітний - близько 5-10% від загального використання процесора під час кожного тестування. Очікування на мережу були незначними (як, наприклад, 3 мс із клієнтом на моїй робочій станції), але вплив процесора був там точно, що, наскільки я переживаю, є досить переконливим. Здається, це зводиться до використання процесора та трохи зайвого IO файлу бази даних. Загальна кількість страт / секунд працює трохи менше 3000, що більше, ніж у виробництві, проте я тестую лише один із десятків запитів на кшталт цього. Чистий ефект сотень запитів, що потрапляють на порожні таблиці зі швидкістю від 300 до 4000 разів на хвилину, тому не був би незначним, якщо мова йде про час процесора. Всі випробування зроблені на простої PE 730xD з подвійним флеш-масивом і 256 ГБ оперативної пам’яті, 12 сучасних ядер.
@ srutzky- гарне мислення. SQLQueryStress, здається, використовує об'єднання з'єднань за замовчуванням, але я все одно подивився і виявив, що так, прапорець для об'єднання з'єднань встановлений. Оновлення для наступного
@ srutzky- Об’єднання підключень, мабуть, не включено у програмі - або якщо воно є, воно не працює. Я простежив профайлер і виявив, що у з'єднаннях є EventSubClass "1 - Неочищений" для подій входу в аудит.
RE: З'єднання підключення. Перевірено веб-журнали та встановлено об'єднання з'єднань. Знайдено більше слідів проти живих та виявлених ознак об’єднання, які не виникають правильно / зовсім:
І ось, як це виглядає, коли я запускаю один запит без приєднання до заселеної таблиці; у винятках написано: "Під час встановлення з'єднання з SQL-сервером сталася помилка, пов’язана з мережею або специфікою. Сервер не знайдений або недоступний. Перевірте, чи ім'я екземпляра правильне та налаштовано SQL Server, щоб дозволяти віддалені з'єднання. (постачальник: Named Pipes Provider, помилка: 40 - Не вдалося відкрити з'єднання з SQL Server) "Зверніть увагу на лічильник пакетних запитів. Пінінг сервера протягом часу, коли створюються винятки, призводить до успішної реакції ping.
Оновлення - два послідовних тестових запуски, однакове навантаження (виберіть * зEmptyTable), пул увімкнено / не увімкнено. Трохи більше використання процесора і багато збоїв, і ніколи не перевищує 500 пакетних запитів в секунду. Тести показують 10 000 Пакетів / сек і відсутні збої при об'єднанні, і близько 400 партій / сек, то багато помилок через відключення об'єднання. Цікаво, чи пов’язані ці збої з відсутністю наявності з'єднання?
@ srutzky- Виберіть Count (*) з sys.dm_exec_connections;
Увімкнено об'єднання: 37 послідовно, навіть після припинення тесту навантаження
Об’єднання відключено: 11-37 залежно від того,
відбуваються чи ні винятки в SQLQueryStress, тобто: коли ці корита відображаються на
графіку Пакет / сек, винятки трапляються на SQLQueryStress, а
кількість з'єднань падає до 11, а потім поступово повертається до 37 коли партії починають досягати максимуму і винятки не відбуваються. Дуже, дуже цікаво.
Максимальне з'єднання обох тестових / активних екземплярів встановлено за замовчуванням 0.
Перевіривши журнали додатків і не можете знайти проблеми з підключенням, доступно лише пару хвилин протоколу через велику кількість та розмір помилок, тобто: багато помилок трасування стека. Колега з питань підтримки додатків радить, що виникає значна кількість помилок HTTP, пов’язаних із підключенням. Виходячи з цього, здавалося б, що програма чомусь неправильно об'єднує з'єднання, і, як наслідок, сервер неодноразово закінчується. Я детальніше розгляну журнали додатків. Цікаво, чи існує спосіб довести, що це відбувається у виробництві з боку SQL Server?
@ srutzky- Дякую. Я завтра перевіру веб-конфігурацію та оновлю. Я думав, хоча про лише 37 підключень - якщо SQLQueryStress робить 12 потоків при 10000 ітерацій = 120 000 виписуваних операторів без об'єднання, чи не означає це, що кожен вибір створює чітке з'єднання з екземпляром sql?
@ srutzky- Weblogics налаштовано для об'єднання з'єднань, тому це повинно працювати нормально. Об'єднання об'єднань налаштовано так у кожній з 4-х урівноважених навантажень веблогів:
- Початкова потужність: 10
- Максимальна ємність: 50
- Мінімальна ємність: 5
Коли я збільшую кількість потоків, які виконують вибір із запиту порожньої таблиці, кількість з'єднань досягає 47. Якщо об'єднання з'єднань вимкнено, я послідовно бачу нижчий макс пакетних запитів / сек (від 10000 до приблизно 400). Щоразу трапляється, що "винятки" в SQLQueryStress трапляються незабаром після того, як партії / сек переходять у жолоб. Це пов'язано зі зв’язком, але я не можу зрозуміти, чому саме це відбувається. Коли тести не виконуються, #connections знижується приблизно до 12.
Якщо вимкнено об'єднання об'єднань, у мене виникають проблеми з розумінням того, чому виникають винятки, але, можливо, це зовсім інше запитання / питання щодо обміну обміну для Адама Маханіка?
@srutzky Цікаво, чому тоді винятки трапляються без включення об'єднання, навіть якщо SQL Server не закінчується підключеннями?
SELECT COUNT(*) FROM sys.dm_exec_connections;
щоб переконатися, що значення сильно відрізняється між включеним об'єднанням або ні. Виходячи з цих помилок, я думаю, було б набагато більше з'єднань, коли об'єднання відключено.
Pooling=false
чи Max Pool Size
?