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

19

Я знаю, что на самом деле есть три вида фрагментации, о которых я должен беспокоиться как администратор баз данных:

  1. Фрагментация индекса в файлах данных SQL, включая фрагментацию кластерного индекса (таблицы). Определите это с помощью DBCC SHOWCONTIG (в SQL 2000) или sys.dm_ db_ index_ Physical_Stats (в 2005+).

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

  3. Физическая фрагментация файлов базы данных на жестком диске. Диагностируйте это с помощью утилиты «Дефрагментация диска» в Windows. (вдохновленный этим прекрасным сообщением в блоге )

Большое внимание уделяется фрагментации индекса (см. Этот отличный ответ Serverfault от Пола Рэндалла), так что это не главное в моем вопросе.

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

  • Прежде всего, актуальна ли физическая фрагментация в Enterprise SAN? Могу ли я / я должен использовать дефрагментацию Windows на диске SAN, или команда SAN использует внутренние утилиты дефрагментации? Является ли анализ фрагментации, который я получаю от инструмента Windows, даже точным при запуске на диске SAN?

  • Насколько велика физическая фрагментация производительности SQL? (Давайте предположим, что внутренний дисковый массив ожидает решения предыдущего вопроса.) Является ли это более крупной сделкой, чем внутренняя фрагментация индекса? Или это действительно та же самая проблема (привод должен делать случайное чтение вместо последовательного чтения)

  • Является ли дефрагментация (или перестройка) индексов пустой тратой времени, если диск физически фрагментирован? Должен ли я исправить один, прежде чем обратиться к другому?

  • Каков наилучший способ исправить физическую фрагментацию файлов в рабочей коробке SQL? Я знаю, что могу отключить службы SQL и запустить дефрагментацию Windows, но я также слышал о методике, когда вы делаете полное резервное копирование, удаляете базу данных, а затем восстанавливаете ее из пустого диска. Этот последний метод рекомендуется? Есть ли восстановление из резервной копии , как это также создавать индексы с нуля, устранение внутренней фрагментации индекса? Или он просто возвращает порядок страниц на тот же, что и при создании резервной копии? (Мы используем резервные копии Quest Lightspeed со сжатием, если это имеет значение.)

ОБНОВЛЕНИЕ : Хорошие ответы на данный момент о том, следует ли дефрагментировать диски SAN (НЕТ) и стоит ли дефрагментация индекса на физически фрагментированных дисках (ДА).

Кто-нибудь еще хочет взвесить лучшие методы для проведения дефрагментации? Или оценка времени, которое, как вы ожидаете, потребуется для дефрагментации большого фрагментированного диска, скажем, 500 ГБ или около того? Очевидно, потому что это время, когда мой SQL-сервер не работает!

Кроме того, если у кого-нибудь есть какая-либо неподтвержденная информация об улучшениях производительности SQL, которые вы сделали, исправив физическую фрагментацию, это тоже было бы здорово. В блоге Майка рассказывается о том, как раскрыть проблему, но не говорится о том, какие улучшения она сделала.

BradC
источник

Ответы:

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-фрагмента, скорее всего, нет.

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

Фрагментация индекса полностью ортогональна фрагментации файла. SQL Server не имеет представления о фрагментации файлов - слишком много уровней виртуализации между ними, чтобы иметь хоть какую-то надежду на разработку реальной геометрии подсистемы ввода-вывода. Фрагментация индекса, однако, SQL знает все о. Не повторяя слишком много из ответа, на который вы уже ссылались, фрагментация индекса не позволит SQL выполнять эффективную проверку дальности сканирования независимо от того, насколько фрагментированы (или нет) файлы на уровне файловой системы. Так что - абсолютно необходимо уменьшить фрагментацию индекса, если вы видите снижение производительности запросов.

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

Надеюсь это поможет!

Пол Рэндал
источник
А, так что же, внутренняя фрагментация индекса фактически меняет поведение оптимизатора, предпочитая полное сканирование вместо поиска нужного диапазона индекса?
BradC
Нет. Оптимизатор не знает, как данные хранятся на диске, кроме того, что существуют индексы, их размер и статистика распределения значений столбцов. Это механизм хранения, который управляет чтением и изменяет размеры отдельных входов / выходов на основе логической фрагментации сканируемой информации.
Пол Рэндал
3

Каков наилучший способ исправить физическую фрагментацию файлов в рабочей коробке SQL?

Я запускаю SYSINTERNALS 'contig в моих файлах базы данных.

См. Http://technet.microsoft.com/en-us/sysinternals/bb897428.aspx

Винсент Бак
источник
Выглядит интересно. Я предполагаю, что поскольку он использует API-интерфейсы дефрагментации Windows, службы SQL должны быть отключены? Или это будет работать, пока сервер / база данных подключены?
BradC
Я успешно использовал его в онлайн-базах данных MSSQL Server. Но, возможно, это были базы данных с небольшим трафиком и небольшими базами данных (менее 10 Гб)
Винсент Бак,
Это отличный инструмент! Я думаю, что приложения для баз данных довольно ограничены, как упоминали другие люди, но я люблю его для других типов дисков. Режим анализа -a безопасен, пока все работает. Я не чувствовал бы себя безопасным, если бы он работал с диском, принадлежащим живому SQL Server.
Кендра
2

Я бы порекомендовал правильно выбрать размер базы данных, выключить сервер 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. Это отличный продукт, который вы можете использовать для настройки своих баз данных, но это не дешевое программное обеспечение.
Хакан Винтер