Фрагментація фізичних файлів бази даних SQL


19

Я знаю, що є насправді три види фрагментації, про які мені потрібно потурбуватись як DBA:

  1. Фрагментація індексу у файлах даних SQL, включаючи кластеризовану фрагментацію індексу (таблиці). Визначте це за допомогою DBCC SHOWCONTIG (у SQL 2000) або sys.dm_ db_ index_ physical stats (у 2005+).

  2. Фрагментація VLF всередині файлів журналу SQL. Запустіть DBCC LOGINFO, щоб побачити, скільки VLF є у кожному з ваших файлів журналу SQL.

  3. Фізична фрагментація файлів бази даних на жорсткому диску. Діагностуйте це за допомогою утиліти "Дефрагментатор диска" у Windows. (натхненний цією чудовою публікацією в блозі )

Багато уваги приділяється фрагментації індексу (див. Цю чудову відповідь сервера за замовчуванням від Пола Рендала), тож це не фокус мого питання.

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

  • Перш за все, чи є фізична фрагментація навіть актуальною для Enterprise SAN? Чи можу я / чи слід використовувати дефрагментатор Windows на накопичувачі SAN, чи команда SAN повинна використовувати внутрішні утиліти дефрагментації? Чи точний аналіз фрагментації, який я отримую від інструмента Windows, навіть точний під час роботи на накопичувачі SAN?

  • Наскільки велика угода - фізична фрагментація продуктивності SQL? (Припустимо, внутрішній масив приводу, до очікування результату попереднього запитання.) Це БІЛЬШЕ угода, ніж внутрішня фрагментація індексу? Або це справді така ж проблема (накопичувач повинен робити випадкові читання замість послідовних читання)

  • Чи є маркуванням часу дефрагментація (або перебудова) індексів, якщо привід фізично фрагментований? Чи потрібно виправити одне, перш ніж звертатись до іншого?

  • Який найкращий спосіб виправити фрагментацію фізичних файлів у виробничому SQL-коді? Я знаю, що можу вимкнути сервіси SQL та запустити Windows Defrag, але я також чув про техніку, коли ви робите повну резервну копію, скидаєте базу даних, а потім відновите з резервної копії на порожній диск. Чи рекомендується ця остання техніка? Чи відновлення такої резервної копії також створює індекси з нуля, виключаючи внутрішню фрагментацію індексу? Або просто повертає порядок сторінки таким же, як і коли було зроблено резервну копію? (Ми використовуємо резервні копії Quest Lightspeed із стисненням, якщо це має значення.)

ОНОВЛЕННЯ : На сьогоднішній день хороші відповіді щодо того, чи слід дефрагментувати SAN-накопичувачі (НІ) та чи дефрагментація індексу досі стоїть на фізично фрагментованих накопичувачах (ТАК).

Хтось ще хотів би зважити на найкращі методи для фактичного проведення дефрагментації? Або підрахунок часу, який ви очікуєте, що знадобиться для дефрагментації великого роздробленого накопичувача, скажімо, 500 Гб або близько того? Відповідно, очевидно, тому що саме в цей час мій сервер SQL знищиться!

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

Відповіді:


9

Я думаю, що ця стаття дає чудовий огляд дефрагментації приводів SAN

http://www.las-solanas.com/storage_virtualization/san_volume_defragmentation.php

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

Якщо ви використовували відображення пристроїв RAW або у вас є прямий доступ до набору RAID, який є LUN, з яким ви працюєте, я можу побачити, що дефрагментація має позитивний ефект, але якщо вам надається "віртуальний" LUN від спільного RAID- 5 комплект, ні.


Відмінна стаття. Що стосується приводів SAN.
BradC

7

Кілька частин цього питання та відповіді:

Фізична фрагментація файлів насправді не актуальна для зберігання Enterprise SAN, як уже вказував Кевін - тому нічого тут додати. Це дійсно зводиться до підсистеми вводу / виводу, і наскільки ви, мабуть, зможете змусити накопичувачі перейти від більш випадкових вводу / виводу при виконанні сканування до більш послідовних вводу / виводу при виконанні сканування. що стосується DAS, то, швидше за все, для складної SAN-шматочки N-кубиків, ймовірно, ви не будете.

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

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

Вам не доведеться робити це в будь-якому конкретному порядку, хоча якщо ви подбаєте про фрагментацію файлової системи, а потім відновите всі ваші індекси та викликаєте більше фрагментації файлової системи, зростаючи кілька файлів на дефрагментованому томі, ви, ймовірно, збираєтесь відмітити. Чи це спричинить якісь проблеми з парфумом? Як обговорювалося вище, це залежить від :-D

Сподіваюся, це допомагає!


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

Ні. Оптимізатор не знає, як зберігаються дані на диску, крім того, що існують індекси, їх розмір та статистика розподілу значень стовпців. Це двигун зберігання, який рухає читати голову та змінює окремі розміри вводу / виводу на основі логічної фрагментації того, що він сканує.
Пол Рандал

3

Який найкращий спосіб виправити фрагментацію фізичних файлів у виробничому SQL-коді?

Я запускаю підключення SYSINTERNALS до файлів бази даних.

Дивіться http://technet.microsoft.com/en-us/sysinternals/bb897428.aspx


Виглядає цікаво. Я припускаю, що з використанням API дефрагментації Windows, SQL-сервіси повинні бути вимкнено? Або це запуститься, коли сервер / база даних є в Інтернеті?
BradC

Я успішно використовував його в онлайн-базах даних MSSQL Server. Але, мабуть, це були низький трафік і невеликі бази даних (менше 10 Гбіт)
Вінсент Бак

Це чудовий інструмент! Я думаю, що програми для баз даних досить обмежені, як це зазначають інші люди, але я люблю це для інших типів накопичувачів. Режим аналізу -a безпечний під час роботи. Я б не відчував себе безпечним для запуску його на накопичувачі, що належить до живого SQL Server.
Кендра

2

Я рекомендую належним чином розмістити db, відключивши sql-сервер, скопіюйте файл бази даних на інший дисковий масив, а потім скопіюйте його назад для дефрагментації. Набагато швидше, ніж на моєму досвіді використання дефрагментів Windows.


1

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

Якщо ваші індекси дефрагментовані, а статистика оновлюється (дуже важливо), і ви все ще бачите введення-вивід як вузьке місце, то ви страждаєте від інших речей, ніж фізична фрагментація. Ви використовували більше 80% накопичувача? У вас достатньо дисків? Чи достатньо оптимізовані ваші запити? Ви робите багато сканування таблиці або ще гірше, що шукаєте індекс, а потім кластерний пошук індексу? Подивіться плани запитів і використовуйте "встановити статистику io on", щоб дізнатися, що відбувається насправді з вашим запитом. (шукайте велику кількість логічних чи фізичних читань)

Будь ласка, дайте мені знати, чи я абсолютно помиляюся.

/ Хокан Вінтер


Ні, ти не помилився. Але намагатися зробити деякі покращення на сервері (якщо можливо) трохи привабливіше, ніж починати занурюватися в 150 000+ виразних операторів SQL, які виконуються під час щотижневих завдань аналізу (не перебільшення. Напевно, заниження, власне)
BradC

Якщо у вас є така ситуація, я рекомендую Veritas I3 проаналізувати ваше оточення, щоб побачити, яке вузьке місце ви страждаєте і що спричиняє вузьке місце. Veritas I3 відслідковує всі заяви і те, як часто вони дзвоняться і якою ціною. Це відмінне програмне забезпечення.
Хакан Вінтер,

1

Можливо, індекси недостатньо оптимізовані для вашої програми, і у вас немає Veritas I3 для оптимізації вашої бази даних, тоді ви можете використовувати такий оператор для пошуку відсутніх індексів:

       SELECT
      mid.statement,
      mid.equality_columns,
      mid.inequality_columns,
      mid.included_columns,
      migs.user_seeks,
      migs.user_scans,
      migs.last_user_seek,
      migs.avg_user_impact,
      user_scans,
      avg_total_user_cost,
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) AS [weight]--, migs.*--, mid.*
   FROM
      sys.dm_db_missing_index_group_stats AS migs
      INNER JOIN sys.dm_db_missing_index_groups AS mig
         ON (migs.group_handle = mig.index_group_handle)
      INNER JOIN sys.dm_db_missing_index_details AS mid
         ON (mig.index_handle = mid.index_handle)
   ORDER BY
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) DESC ;

Або такий собі оператор, щоб знайти індекси, які не використовуються у вибраних операторах і знижує продуктивність оновлення / вставки:

    CREATE PROCEDURE [ADMIN].[spIndexCostBenefit]
    @dbname [nvarchar](75)
WITH EXECUTE AS CALLER
AS
--set @dbname='Chess'
declare @dbid nvarchar(5)
declare @sql nvarchar(2000)
select @dbid = convert(nvarchar(5),db_id(@dbname))

set @sql=N'select ''object'' = t.name,i.name
        ,''user reads'' = iu.user_seeks + iu.user_scans + iu.user_lookups
        ,''system reads'' = iu.system_seeks + iu.system_scans + iu.system_lookups
        ,''user writes'' = iu.user_updates
        ,''system writes'' = iu.system_updates
from '+ @dbname + '.sys.dm_db_index_usage_stats iu
,' + @dbname + '.sys.indexes i
,' + @dbname + '.sys.tables t
where 
    iu.database_id = ' + @dbid + '
and iu.index_id=i.index_id
and iu.object_id=i.object_id
and iu.object_id=t.object_id
AND (iu.user_seeks + iu.user_scans + iu.user_lookups)<iu.user_updates
order by ''user reads'' desc'

exec sp_executesql @sql

set @sql=N'SELECT
   ''object'' = t.name,
   o.index_id,
   ''usage_reads'' = user_seeks + user_scans + user_lookups,
   ''operational_reads'' = range_scan_count + singleton_lookup_count,
   range_scan_count,
   singleton_lookup_count,
   ''usage writes'' = user_updates,
   ''operational_leaf_writes'' = leaf_insert_count + leaf_update_count + leaf_delete_count,
   leaf_insert_count,
   leaf_update_count,
   leaf_delete_count,
   ''operational_leaf_page_splits'' = leaf_allocation_count,
   ''operational_nonleaf_writes'' = nonleaf_insert_count + nonleaf_update_count + nonleaf_delete_count,
   ''operational_nonleaf_page_splits'' = nonleaf_allocation_count
FROM
   ' + @dbname + '.sys.dm_db_index_operational_stats(' + @dbid + ', NULL, NULL, NULL) o,
   ' + @dbname + '.sys.dm_db_index_usage_stats u,
    ' + @dbname + '.sys.tables t
WHERE
   u.object_id = o.object_id
   AND u.index_id = o.index_id
    and u.object_id=t.object_id
ORDER BY
   operational_reads DESC,
   operational_leaf_writes,
   operational_nonleaf_writes'

exec sp_executesql @sql

GO

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

(Я знаю, ця публікація є трохи темою, але я подумав, що вам може бути цікаво, оскільки це стосується стратегії індексування)

/ Хокан Вінтер


Відмінні сценарії, у мене дуже схожі. На жаль, у нас все ще 40% SQL 2000 (включаючи відповідний сервер), який не має жодного еквівалента цим DMV-адресам "відсутнього індексу".
BradC

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