Підвищити швидкість видалення для SQL Server


12

У нас величезна виробнича база даних, її розмір становить близько 300 ГБ. Чи є якийсь підхід до підвищення ефективності запиту на видалення? Зараз швидкість видалення становить від 1-10 к в хвилину, для нас це дуже повільно.


2
1000 рядків в хвилину звучить надзвичайно повільно. У вас виникає блокування? Або так само повільно вибирати рядки, які б підказували необхідність індексувати?
Джеймс Z

Можливо, вам доведеться створити індекс, щоб покрити ваші критерії видалення.
Гінден

6
Немає достатньо деталей, щоб дати відповідь. Який запит ви виконуєте? Чи є у вас індекси в колонках з критеріями (якщо такі є)? У вас є тригери при видаленні? ...
Себастьян Севрін

3
Ви намагаєтесь видалити мільярд рядків одночасно? Можливо, ви чекаєте на автоматичне зростання після авторостання після авторостання? (Це більш ніж ймовірно, що це активність журналу, яку ви чекаєте, а не фактична активність видалення.) Дивіться цю статтю ...
Аарон Бертран

3
Також. Якісь закордонні ключові обмеження? Будь ласка, надайте повне визначення таблиці, запиту та плану виконання.
Мартін Сміт

Відповіді:


20

Якщо ви намагаєтесь видалити велику кількість рядків в одному операторі, то, ймовірно, вас чекає активність журналу. Отже ви можете:

  1. Переконайтеся, що ваш журнал має достатній розмір, щоб події росту не уповільнили вас. За замовчуванням ваш журнал, ймовірно, починається з 1 МБ із зростанням 10%. Події зростання дорогі, і якщо ви реєструєте навіть 10 ГБ делетів, це знищить продуктивність не тільки зараз, але й у майбутньому (завдяки тому, що це робить для VLF).
  2. Якщо ви видаляєте всю таблицю, використовуйте TRUNCATEабо DROP/ CREATE.
  3. Якщо ви видаляєте більшу частину таблиці, використовуйте, SELECT INTOщоб перенести дані, які ви хочете зберегти, в іншу таблицю, а TRUNCATEпотім перемістіть невелику частину назад. (Або просто скиньте стару таблицю, перейменуйте нову та повторно застосуйте обмеження / дозволи тощо)
  4. Мінімізуйте вплив журналу в першу чергу, видаляючи дані в шматки замість усіх відразу. Дивіться цю статтю . Ви також можете розглянути можливість тимчасового переходу на просте відновлення, так що вам доведеться лише CHECKPOINTочистити журнал замість того, щоб робити резервні копії журналу, але вам потрібно обов’язково встановити його назад та взяти нову повну резервну копію, щоб знову запустити ланцюг журналу. .

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

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

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

Чи може тимчасове відключення обмежень FK може покращити запит?
Лев Z

3

Існують деякі підказки, але яку версію ви використовуєте? Це корпоративне видання? У будь-якому випадку:

  1. Якщо можете, перемістіть журнал транзакцій на більш швидкий диск
  2. Проаналізуйте, куди . Чи буде він використовувати індекс для ідентифікації записів для видалення? Якщо ні, чи можете ви додати індекс?
  3. Чи є у вас якийсь індекс на столі, який ви можете скинути? Якщо так, киньте їх.
  4. У вас є сторонні ключі проти цієї таблиці? Вони дійсно можуть уповільнити видалення.
  5. Якщо у вас є корпоративне видання, а вузьким місцем є диск IO, компресія на рівні рядків може допомогти вам трохи допомогти (чи ні, залежно від ваших даних)
  6. Чи можете ви розділити таблицю? Локальні індекси та падіння розділів можуть бути швидшими.
  7. Дослідіть, де знаходиться вузьке місце, за допомогою монітора активності.

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


0

Ви повинні спробувати видалити їх фрагмент за допомогою chunk, ймовірно, видалити в циклі, кожну ітерацію видалення це власна транзакція, а потім очистити журнал в кінці кожної ітерації циклу.

Крім того, вам потрібно буде знайти номер, який ви збираєтеся використовувати як значення в шматок для видалення записів. Це вимагає ретельного тестування, було б краще, якщо ви спершу зможете перевірити значення шматка в UAT.

Про те, як діяти, посилається на розділення великих операцій видалення на шматки


0

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

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


це був точно мій випадок. Це трохи ризиковано відключити contraint, але видалення пішов з 1 ряду / seocnd 500 / другий
Jurion

0

Додавання ще кількох балів ...

  1. Спробуйте перевірити, чи має присудок індекс, а також перегляньте статистику.
  2. Якщо ви видаляєте велику кількість рядків, а також не хочете параметр таблиці темп. Перейдіть на tablockваріант.
  3. Перевірте, чи є у вас тригери, зокрема після видалення тригерів.

Щоб отримати додаткову допомогу, опублікуйте використаний вами запит, інформацію таблиці та будь-яку інформацію про блокування.

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