Запит додатків на порожні таблиці


10

Моя компанія використовує додаток, який має досить великі проблеми з продуктивністю. Існує ряд проблем із самою базою даних, над якими я працюю, але багато проблем пов'язані виключно із додатком.

Під час мого розслідування я виявив, що в базу даних 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 сучасних ядер. Це вихід із SQLSentry

@ 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 не закінчується підключеннями?


1
Пітер, маючи на увазі найновіші оновлення щодо об’єднання з'єднань, схоже, вам зараз потрібно повторно запустити свої тести з SQLQueryStress, але з вимкненням пулу підключення . Це було б більш точним відображенням ефектів роботи програми, і я вважаю, що це покаже збільшення використання процесора і навіть використання оперативної пам’яті.
Соломон Руцький

1
Петро, ​​у вас встановлена ​​максимальна кількість з'єднань для сервера? Я здогадуюсь, що без об'єднання ви стикаєтеся із проблемою занадто багато з'єднань. Цікаво, чи ваш додаток коли-небудь отримує цю помилку. Крім того, якщо можливо повторно запустити цей останній тест ще раз (як із включеним об'єднанням, так і без нього), коли тест виконується для кожної з цих двох конфігурацій, запустіть a, SELECT COUNT(*) FROM sys.dm_exec_connections;щоб переконатися, що значення сильно відрізняється між включеним об'єднанням або ні. Виходячи з цих помилок, я думаю, було б набагато більше з'єднань, коли об'єднання відключено.
Соломон Руцький

1
Петро, ​​37 зв'язків здається жахливо низьким максимумом. З огляду на те, що обмеження для з'єднання встановлено на 0 (тобто необмежене), чи пов'язана системна пам'ять? Також об'єднання з'єднань повинно бути включене за замовчуванням, але контролюється клієнтом. Це додаток .NET додаток? Не потрібно використовувати для об'єднання з'єднань, але допоможе знати, щоб знайти причину цього. І чи можете ви бачити, який рядок з'єднання використовується? Вказує це Pooling=falseчи Max Pool Size?
Соломон Руцький

1
Пітер, кожен з 12 потоків створює своє власне з'єднання за запитом, послідовно для ітерацій 10k. Тому без об'єднання з'єднання можна зруйнувати, як тільки код закриває з'єднання. Пул збереже з'єднання навколо для повторного використання. Тож має сенс, щоб кількість з'єднань була послідовною під час використання пулу. Не впевнений, чому 37 без додаткової інформації. Скільки є з'єднань, коли не виконується тест? Якщо відмовитись від цієї цифри, можна краще вказати кількість створених тестуванням.
Соломон Руцький

1
Пул з'єднання підтримується на клієнта, а не на сервері. Таким чином, WebLogics і SQLQueryStress повинні мати власні пули підключення (з точки зору розмірів min_pool та max_pool тощо). Що стосується "Якщо вимкнено об'єднання з'єднань, я бачу нижчий максимум запитів пакетів / сек": це має сенс, оскільки для кожного з'єднання з додатку потрібно більше часу для автентифікації та ініціалізації сеансу тощо. Саме тому існує об'єднання з'єднань: - ).
Соломон Руцький

Відповіді:


7

Я б підозрював, що реальна механіка надсилання запиту, його підтвердження, обробки, повернення та підтвердження отримання заявкою сама по собі матиме вплив на продуктивність.

Так, і є навіть деякі додаткові фактори, але ступінь впливу будь-якого з них на вашу систему неможливо сказати без аналізу системи.

Зважаючи на це, ви запитуєте, що може бути проблемою, і є деякі речі, які слід зазначити, навіть якщо деякі з них не є чинником вашої конкретної ситуації. Ви кажете, що:

У нас близько 300 порожніх таблиць, і деякі з цих таблиць запитуються до 100-200 разів на хвилину.

  • Порожні таблиці, які не запитуються, не є проблемою. Але я думаю, ви також можете мати на увазі, що їх усіх запитують, тільки що деякі потрапляють набагато більше, ніж інші.
  • Розробка запиту та генерація плану виконання не повинні бути великою проблемою, якщо поданий текст запиту залишається однаковим для всіх дзвінків. SQL Server хеширует текст запиту та шукає його в кеші плану. Якщо він знайдений, він не повторить ні кроки розбору, ні компіляції (поки план не буде видалений з кешу).
  • Будь-яка таблиця, порожня або непорожня, потребує принаймні "загального" блокування, щоб вказати, що ресурс використовується. Це не дозволяє операціям, які потребують ексклюзивних блокувань (додавання / зміна / видалення стовпців тощо), не вносять зміни під час використання ресурсу. Блокування та розблокування, навіть якщо вони виконані менше ніж 1 мілісекунда, оскільки немає даних, все ж потрібні системні ресурси (пам'ять і процесор) для управління цими операціями блокування.
  • Навіть не маючи набору результатів, які повертаються до програми з SQL Server, все одно така сама кількість мережевого трафіку надходить на SQL Server, незалежно від того, запит дає результати чи ні. Текст запиту чи назви збереженої процедури потрібно надіслати. І навіть якщо результати не повернуться, SQL Server все одно повинен надіслати кілька мережевих пакетів, що містять структуру набору результатів, на додаток до пакетів, що повідомляють клієнту, що набір результатів починається (навіть якщо рядків не знайдено), а потім, що набір результатів є закінчення і має бути закритим. І можуть бути додаткові повідомлення з друкованих виписок та / або підрахунків рядків.
  • Для підключення до SQL Server потрібна деяка кількість системних ресурсів. Для обробки автентифікації потрібні процесор і пам'ять (а також мережеві пакети вперед і назад), і це також потребує часу. Ось чому існує об'єднання об'єднань: щоб скоротити цей рахунок.
  • Навіть за допомогою підключення підключення до зменшення використання системних ресурсів, SQL Server все ще потребує підтримання цих з'єднань, і для цього потрібна пам'ять і мінімальний процесор.
  • Навіть не маючи рядків і, отже, дуже швидкий час виконання, запит все ще виконувався. Навіть якщо було 10 або 10 000 рядків, і ті були витягнуті з буферного пулу (тобто пам'яті), оскільки вони часто використовуються, нитка все одно повинна виконати цю роботу. І нитка, яка працює над цим марним запитом, не працює над фактичним корисним запитом.

Це може бути навіть більше, але це повинно допомогти зрозуміти речі. І майте на увазі, що як і більшість питань щодо продуктивності, все це питання масштабу. Усі вищезазначені предмети не є питаннями, якщо їх вдаряють раз на хвилину. Це як тестування змін на вашій робочій станції або в базі даних розробок: вона завжди працює лише з 10 - 100 рядками в таблицях. Перемістіть цей код на виробництво, і він займе 10 хвилин, і хтось неодмінно скаже: "ну, це працює на моїй коробці" ;-). Це означає, що ви бачите проблему лише завдяки великій кількості дзвінків, які ви робите, але це така ситуація, яка існує.

Отже, навіть при 1 мільйоні непотрібних, 0 запитів рядків, це становить:

  • додаткові 2 мільйони операцій блокування (кожен замок повинен бути розблокований, правда?). це переважно витрати часу, витраченого на марну операцію замість корисної операції.
  • більше мережевого трафіку, який може наблизити вас до насичення (не впевнений, наскільки це можливо, але все ж)
  • підтримується більше з'єднань, які займають більше пам’яті. Скільки невикористаної фізичної оперативної пам’яті у вас є? цю пам'ять краще використовувати для запуску запитів та / або кешу плану запитів. Найгіршим буде те, що у вас немає фізичної пам’яті, і SQL Server повинен почати використовувати віртуальну пам’ять (своп), оскільки це сповільнює роботу (перевірте свій журнал помилок SQL Server, щоб дізнатися, чи надходять повідомлення про запам’ятовування пам’яті).

    І на всякий випадок, коли хтось згадує, "ну, є об'єднання з'єднань". Так, це безумовно допомагає зменшити кількість необхідних підключень. Але запити, що надходять до 200 разів на хвилину, це велика кількість паралельних дій, і для законних запитів все ще потрібно існувати. Зробіть a, SELECT * FROM sys.dm_exec_connections;щоб побачити, скільки активних зв’язків ви підтримуєте.

  • незважаючи ні на що інше, це все одно щонайменше 1 мільйон разів протягом кожного дня, що нитка, яка могла б зробити щось корисне, була замість цього недоступною.

Якщо я не помиляюся з приводу того, що я тут висловлював, то мені здається, що навіть у малому масштабі, це тип DDoS-атаки на вашу систему, оскільки вона затоплює мережу та ваш SQL Server із фальшивими запитами , не дозволяючи реальним запитам потрапляти на SQL Server або оброблятись на SQL Server.


1

Якщо таблиці потрапляють 100-200 разів на хвилину, то вони (сподіваємось) на пам'ять. Навантаження на сервер дуже дуже низька. Якщо у вас на сервері баз даних високий процесор або пам'ять, це, швидше за все, не проблема.

Так, запити беруть спільні блокування, але, сподіваємось, вони не блокують жодних блоків оновлення, а також не блокуються жодним блокуванням оновлення. Чи маєте ви будь-яке оновлення, вставлення чи видалення в цих таблицях. Якщо ні, то я б просто відпустив це - якщо у вас виникають проблеми з продуктивністю, у вас повинно бути більше риби для смаження з точки зору сервера бази даних.

Я провів тест на 100 000 виділених лічильників (*) на порожній таблиці, і він пробіг за 32 секунди, а запити були над мережею. Отже 1/3 мілісекунди. Якщо ваша мережа не перевантажена, це навіть не впливає на клієнта. Якщо у вас виникають основні проблеми з продуктивністю, ці 1/3 мілісекунди порожні запити - це не те, що вбиває додаток.

І це може бути лише частиною лівого з'єднання, що захоплює деякі дані статичного типу, які не є частиною поточної програми. Це може бути пов'язане з іншими запитами, тому це не зайва поїздка. Якщо так, то це неохайно, але це навіть не викликає більше трафіку.

Тож назад, щоб подивитися на фактичні твердження. Ви бачите якісь оновлення, додавання чи видалення в цих таблицях?

Так, багато порожніх таблиць і запитів до порожніх таблиць є вказівкою неохайного кодування. Але якщо у вас виникають основні проблеми з продуктивністю, це не є причиною, якщо у вас не відбудуться дійсно неохайні операції запису з цими таблицями.


Скільки інших користувачів на SQL Server виконували запити, коли ви робили тест 100k запитів? Я не кажу, що я правий, і ви помиляєтесь, але якби ви були єдиним у системі чи одним із небагатьох, то, природно, ви не побачили б великого впливу. Питання блокування не було проблемою блокування, це було лише питанням ресурсів, які він вимагає від SQL Server для блокування та розблокування цих сторінок даних, навіть якщо вони завжди знаходяться в буферному пулі. Це все ще робиться робота. І планувальники не безмежні.
Соломон Руцький

І я не кажу, що ви помиляєтесь. Інші користувачі чи ні, це все ще є дійсною мірою, скільки часу знадобилося і міра ресурсів. Зазначене навантаження становить 100-200 в хвилину. 100 000 від одного клієнта за 30 секунд перевищує це завантаження в коефіцієнт від 200 до 400. Якщо блоків оновлення немає, тоді, якщо він прийшов від одного клієнта або 100, це не має ніякої різниці. Ваша відповідь передбачає, що є або перевантажена мережа, або SQL-сервер, і виходячи з питання, якого ви цього не знаєте. Якби це DDoS-атака, то було б більше як 100 / сек (не хвилина), і це не було б проти порожнього столу.
папараццо

Правильно, виходячи з питання, яке ми не знаємо достатньо, щоб звузити його, тому я говорив, що ці речі можуть бути проблемою залежно від обставин. І справа DDoS була лише аналогією, головним чином, заснованою на формулюванні оригінального запитання, що передбачало, що кілька разів потрапляють під цю швидкість, а також багато інших потрапляють також рідше.
Соломон Руцький

Я вважаю це цінною відповіддю в тому сенсі, що перший абзац підсумовує це дуже добре: "Якщо у вас немає високого ЦП або пам'яті на сервері баз даних, це, швидше за все, не проблема". У нашому випадку ми маємо високий рівень використання процесора в певний час дня, і тому додатковий тиск на процесор, здається, є фактором, заснованим на моїх тестуваннях.
Пітер

Примітно, я цитував лише запити, що виконуються 100-200 разів / хвилину, коли насправді є близько 50 запитів до цих порожніх таблиць із кількістю виконання між 200-4000 / хвилиною. Ефект запиту порожніх таблиць з такою частотою суттєво впливає на процесор, навіть у кращому випадку, коли параметризовані запити виконуються неодноразово, тому план, дані тощо - все в пам'яті.
Пітер

0

Загалом для кожного запиту виконуються наступні кроки:

  1. Запит від Заявки.
  2. База даних Аналіз запиту.
  3. Двигун бази даних перевіряє, чи зберігається цей запит вже в ОЗУ. використовувати план виконання, якщо він існує в Пам'яті.
  4. якщо його немає в оперативній пам’яті, двигун бази даних перевіряє наявність наявних статистичних даних щодо об’єктів запиту та визначає план виконання.
  5. Запустіть план виконання, використовуйте введення-вивід для отримання даних з диска.
  6. відповідь на заявку.

багато запитів, як ви згадували, можуть спричинити додаткове навантаження на систему, яка вже є великою - додаткове навантаження на з'єднання, процесор, оперативну пам’ять та введення / виведення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.