Продуктивність вставки збільшується під навантаженням: чому?


19

У мене є фрагмент коду, який виконує вставки в сильно денормалізовані таблиці. У таблицях розміщено кількість стовпців від ~ 100 до 300+. Це SQL Server 2008 R2, який працює на Windows Server 2008.

Кожна вставка складається з вставки до декількох таблиць в рамках однієї транзакції. Деякі вставки збираються NHibernate, але деякі не можуть бути, але все ж вони під однією транзакцією.

Коли я виконую вставки, скажімо, 500 разів, повторно викликаючи фрагмент коду, який виконує вставку, я отримую в середньому ~ 360 мс.

Дивним бітом є те, що коли я запускаю тестовий код одночасно за допомогою 4-х процесів (той самий exe запускається з чотирьох різних командних підказок під Windows Server 2008), ефективність вставки за виклик стає набагато кращою. Я бачу сплески, які проходять так само швидко, як 90 мс (майже на X4 швидше). Я вимірюю час вставки з коду.

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

Пропозиції щодо методів моніторингу SQL Server для розуміння того, що відбувається на рівні db, так само вітаються.

Відповіді:


15

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

Щоб визначити, чи є коефіцієнт пропускної здатності / змиву журналу транзакцій, слідкуйте за:

Подивіться на досягнення внутрішніх меж. У SQL Server 2008 R2 може бути максимум 32 видатних (асинхронних) потоку вводу / виводу журналу в базі даних для 64-розрядних версій (лише 8 на 32-бітних). Також існує обмеження загального розміру для видатних вводу-виводу в розмірі 3840 КБ.

Більше інформації та подальшого читання:


12

Все, що говорить @PaulWhite, плюс ...

Якщо у вас є сторонні ключі, кожна вставка потребує перевірки на кожній таблиці, на яку посилається. Мені це звучить так, як ти є, оскільки ти лише набираєш 360 мс, що мені стає повільним.

У будь-якому випадку, перевірка цих таблиць значно допомагає тим, що ці дані вже є в ОЗУ, а не завантажувати їх на диск.

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

Це також може бути ефективним кешуванням плану, і що ваші запити потрібно збирати вперше, з наступними дзвінками, щоб уникнути цієї фази.


Дякую Роб. Моя проблема продуктивності пов'язана з великою кількістю таблиць, які використовуються під час вставки. Чужих ключів немає, я видалив їх з міркувань продуктивності, і моя модель та вимоги домену дозволяють мені це робити. Я не завантажую дані в ОЗУ, і мої вставки динамічно формуються вхідними запитами, які постійно змінюються. Я в основному зловживаю схемою зірки / сніжинки (ish) для OLTP і намагаюся піти з найкращими можливостями.
mahonya

2
@mahonya, навіть якщо ви явно не завантажуєте дані в оперативну пам’ять, SQL Server повинен спершу прочитати потрібний індекс і сторінки даних у кеш-пам'яті перед виконанням операції з вставкою. Одночасні потоки вставки можуть мати ефект нагрівання кешу таким чином, що один потік створює накладні дані, а другий отримує доступ до даних у кеші.
Дан Гузман

Дякую @DanGuzman - і так, махонья, є велика ймовірність, що ваш кеш буде добре прогрітий. Я буду перевіряти ваші очікування, щоб побачити, чи фізичне введення-виведення спричиняє ваше вузьке місце.
Роб Фарлі

Дякуємо @DanGuzman Погодився, прискорення кеш-пам'яті індексу db - це те, що я звик бачити в постграфах, я, мабуть, неправильно зрозумів інформацію Роба.
mahonya

-3

деякі сервери / cpus / os пам'ятають закономірності. як кеш.

Оскільки ви робите одне і те саме 4 рази, я впевнений, що є способи вирізати кути. Я здогадуюсь, що перший спосіб ви це зробите, він вважає це одним довгим процесом (example1), але другим способом є бачить повторно використаний код і запускає його як кеш (example2), або це може бути перший процес - це великий, щоб вмістити все це в (ram example3).

example1: 0111110000110111110000111011111000011110111110000

example2: 0111110000 | 11 | 0111110000 | 111 | 0111110000 | 1111 | 0111110000

example3: 0111110000011111000001111100000111110000 example3: петля: 0111110000

Я знаю, сервер ubuntu робить це з неодноразовими запитами mysql. Я можу зберегти їх у кеші, хоча насправді єдиною різницею у часі є 10-40мм, але це доповнює. Коли я навчався в школі, там проходили заняття, які показали, що ти повинен змусити програми (perl / php) використовувати цей кеш, щоб швидше.

Але це може залежати від програми, що це за мова, для чого вона складена або як вона була запрограмована.

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