У меня есть база данных SQL, которая размещена на Azure. Проблема в том, что размер выходит из-под контроля, я могу увидеть до 99% фрагментации в кластерных индексах первичного ключа.
Я могу перестроить все остальные индексы с online=on
опцией, и это не повлияет на производительность. Размер одного из индексов PK Clustered превышает 200 ГБ, и для этого a REBUILD...WITH (ONLINE=ON)
вызывает блокировку.
У нас есть пользователи из всех часовых поясов, которые обращаются к сайту, поэтому я не могу найти время, когда я могу перестроить индекс в автономном режиме.
Какова лучшая стратегия для перестройки больших индексов без простоев на сайте?
Я считаю, что реорганизация не поможет, так как фрагментация составляет 99%. Проблема в том, что стол заблокирован даже в режиме онлайн. Основная проблема заключается в том, что индекс превышает 200 ГБ. Первичный ключ является целым числом.
REORGANIZE
уменьшит фрагментацию конечных страниц и уменьшит компактность, какREBUILD
, впрочем, и менее эффективно. Вы уверены, что большой размер происходит из-за фрагментации? Что такое коэффициент заполнения?Ответы:
Хотя уже немного поздно, я собираюсь дать ответ с надеждой, что он поможет или, по крайней мере, отвергнет некоторые дополнительные идеи / комментарии по этому вопросу, потому что я думаю, что это хороший вопрос.
Во-первых, и я не знаю, делаете ли вы это или нет, но, пожалуйста, не думайте, что высокие уровни фрагментации в индексе всегда будут приводить к снижению производительности. Устаревшая статистика (например, sys.dm_db_stats_properties ) и большое количество пустого пространства на странице (т. Е. Столбец avg_page_space_used_in_percent в sys.dm_db_index_physical_stats dmv ) имеют большее отношение к проблемам производительности, чем только фрагментация. Да, сильно фрагментированные индексы будут генерировать больше упреждений при чтении, и вы, как правило, видите устаревшую статистику и более высокие уровни пробелов на странице в сочетании с фрагментацией, но фрагментация напрямую не связана с оптимизацией плана запросов или с тем, сколько памяти загружает индекс с диска будет на самом деле потреблять. На планы запросов влияет статистика, и ваш объем памяти увеличивается с появлением большего количества пустого пространства . Например, индекс, который фрагментирован на 99%, но имеет среднее значение менее 5%. Пробелы и актуальная статистика, скорее всего, не вызовут у вас резких проблем с производительностью по сравнению с плохим планом выполнения из-за устаревшей статистики или постоянной подкачки индекса, который слишком велик для того, чтобы полностью поместиться в памяти, потому что существует значительный объем пустого пространства присутствует на странице.
Если фрагментация действительно является проблемой , вы можете уменьшить ее, ОНЛАЙН, выполнив
ALTER INDEX ... REORGANIZE
заявление, определенное Дэном Гусманом в комментариях. Это не создаст такой упорядоченный индекс, какREBUILD
операция, но уменьшит вашу фрагментацию. Ключевым моментом здесь является определение окон более низкого использования в вашей базе данных и запускать его тогда. Это может быть 15 минут или несколько часов, очевидно, чем дольше, тем лучше, но ключевой момент здесь заключается в том, что эта операция не выполняет откат и сохраняет достигнутый прогресс, даже если вы убьете его в середине выполнения.Если в идеальном мире, где ваша фрагментация была устранена, имеет ли смысл использовать разбиение этой таблицы? База данных SQL Azure допускает разбиение таблиц, и у Microsoft есть отличная статья, в которой изложены некоторые стратегии разделения для базы данных SQL Azure . Если ваши данные не являются летучими, их разбиение может помочь сократить потребности в обслуживании, а в сочетании со сжатием таблиц вы даже сможете уменьшить общий объем памяти. Более ранний ответ Альберто Мурильо намекает на использование горизонтального разбиения основанный на области данных, и этот подход может помочь создать некоторые окна обслуживания для вас, так как ваши данные будут более региональными, а не глобальными.
Переход к секционированной таблице не будет легко с отсутствием в настоящее время окна обслуживания, но вы можете быть в состоянии использовать подход , изложенный Мария Zakourdaev , которая использует секционированные представления поверх текущей таблицы и новая секционированная таблица , чтобы начать секционирование будущие данные. Со временем (и, надеюсь, ваши старые данные будут удалены), вы можете в конечном итоге полностью перейти к разделенной таблице. Опять же, я не знаю ваших данных или приложения, но, возможно, вы можете использовать этот подход.
источник
Во-первых, важно учитывать, имеет ли значение фрагментация.
Если ваш запрос выполняет поиск только по одной строке, вы можете вообще не заметить фрагментации. В современных SAN кэширование на уровне SAN может сделать физические операции ввода-вывода достаточно быстрыми, чтобы фрагментация не имела значения. На SSD случайный шаблон ввода-вывода, вызванный сканированием фрагментированного индекса, может фактически привести к более высокой производительности, чем не фрагментированные данные.
Часто люди замечают, что перестройка индекса исправляет проблему производительности. Перестройка индекса также создает свежую статистику. Может случиться так, что реальное исправление - это свежая статистика, а не перестройка индекса.
UPDATE STATISTICS...WITH FULLSCAN
может быть более дешевым, быстрым и менее навязчивым способом решения той же проблемы с производительностью.Если у вас нет проблем, вызванных фрагментацией, то вы могли бы потратить значительное время и усилия без какой-либо реальной выгоды.
Во-вторых, существует два вида фрагментации:
Физическая фрагментация. Это то, о чем думает большинство людей, когда они думают о фрагментации. Страницы вышли из строя и должны быть переупорядочены. При сканировании индекса этот тип фрагментации может иногда быть проблемой. Я вообще заметил, что это имеет наибольшее влияние на производительность при физическом чтении. Если вы смотрите на результаты
sys.dm_db_index_physical_stats
, этот номер являетсяavg_fragmentation_in_percent
столбцом.Фрагментация низкой плотности. Эта фрагментация вызвана страницами, которые только частично заполнены данными. У вас низкая плотность данных, потому что ваши данные распределены по большему количеству страниц, чем необходимо. В результате для чтения данных требуется больше операций ввода-вывода, поскольку данные распределены по большему количеству страниц, чем необходимо. Это может повлиять как на логическое, так и на физическое чтение. Если вы смотрите на результаты
sys.dm_db_index_physical_stats
, этот номер являетсяavg_page_space_used_in_percent
столбцом. Этот столбец заполняется только при использованииSAMPLED
илиDETAILED
режиме.Итак, что вы делаете по этому поводу:
Физическая фрагментация : если вы просто гоняетесь за большими числами
avg_fragmentation_in_percent
, подумайте, не теряете ли вы время. Убедитесь, что у вас есть фактический запрос, который работает плохо, и используйте тестовую среду, чтобы подтвердить, что вы исправляете проблему, устраняя фрагментацию.Вы можете решить физическую фрагментацию, выполнив
ALTER INDEX...REORGANIZE
.REORGANIZE
Операция онлайн, перемещение страниц по одному за раз , чтобы реорганизовать их обратно в физический порядок. Если вы уничтожитеREORGANIZE
оператор на полпути, любая работа, которая уже была выполнена, будет сохранена - будет откатываться только одна страница, которая в данный момент перемещается. ВыполнениеREORGANIZE
операции с большой таблицей, которая сильно фрагментирована, может потребовать больше общего пространства журнала транзакций, а в режиме полного восстановления может создать значительное количество резервных копий журнала транзакций. ДляREORGANIZE
сильно фрагментированного индекса может также потребоваться больше времени, чем дляREBUILD
него.Вы часто будете встречаться с советами выполнять операции с
REBUILD
сильно фрагментированными индексами, а не с.REORGANIZE
Это происходит потому, что восстановление с нуля может быть более эффективным. Однако реорганизация может быть «более оперативной» операцией и иногда предпочтительна даже для сильно фрагментированных индексов.Фрагментация низкой плотности не может быть исправлена
REORGANIZE
. Это можно исправить только с помощьюALTER INDEX...REBUILD
. Выполнив индекс сONLINE=ON
, вы сможете минимизировать блокировку. Тем не менее, по-REBUILD
прежнему необходимо на мгновение заблокировать, чтобы заменить старый индекс на новый. В очень загруженной системе достижение этой исключительной блокировки иногда может быть проблемой. Вы должны быть в состоянии подтвердить, если у вас возникла эта проблема, используя что-то вроде sp_whoisactive для проверки блокировки во время перестройки и просмотра сведений о блокировках и ожиданиях. Использование этойWAIT_AT_LOW_PRIORITY
опции может быть полезно, если вы знаете, что наступает период низкого уровня использования, и ваша перестройка может «проскользнуть» для этого обмена, когда активность падает достаточно низко для достижения этой блокировки. Обратите внимание, что длительныйREBUILD
Операция также будет длительной открытой транзакцией. У длительных открытых транзакций могут быть свои проблемы, связанные с использованием / повторным использованием журнала транзакций. Если вы используете зеркалирование или группы доступности, существуют также соображения относительно повторного выполнения журнала транзакций на вторичной реплике.источник
REORGANIZE
. С BOL : «Реорганизация также сжимает индексные страницы». Ну, так что пока текущий индекс FILLFACTOR будет позволять плотность, которую вы ищете.уведомление
После этого комментария:
... Я вижу, как этот подход не будет работать.
Я оставлю этот ответ как пример того, чего не следует делать.
Если у вас есть лишние 200 ГБ свободного пространства в вашей базе данных Azure, вы можете получить хитрость при «перестроении», скопировав ваши данные в совершенно новую таблицу и упорядочив ее там.
Пытаться:
LiveTable
в пустуюNewTable
LiveTable
вNewTable
LiveTable
вOldTable
NewTable
вLiveTable
Очевидно, используйте имя вашей таблицы вместо
LiveTable
.источник
В идеале, если индекс хорошо спроектирован, нам не нужно возиться с механизмом блокировки.
Мне кажется, что вам нужно принять блокировку для дефрагментации кластеризованного индекса. Если есть хорошие шансы на то, что это произойдет снова, тогда посмотрите на изменение структуры кластерного индекса (он должен быть узким, уникальным, статичным и постоянно увеличивающимся).
Я не уверен, какую версию SQL Server вы используете, но вы можете попробовать следующее в 2012 году:
SET DEADLOCK_PRIORITY LOW
- Это говорит движку, что перестройка индекса должна стать жертвой тупика, когда / если он произойдет.MaxDOP = 1
- Значение MaxDOP ограничивает общее количество логических процессоров, используемых параллельно для создания индекса (2005 г. и выше - только версия Enterprise).Вы также можете изменить конфигурацию блокировок страницы / строки, но я бы не стал это делать без тестирования. Вы можете просто сделать блокировку хуже, особенно если это плохо спроектированный индекс.
Начиная с 2014 года, существует следующая опция, которая в основном сообщает движку, что нужно продолжить выполнение других сеансов и ожидание операции индексирования в сети:
источник
Я использовал тот же подход, что и Oreo, описанный выше, с большим успехом! Единственное, чего не хватает, так это того, что вам нужно запустить скрипт обновления после того, как вы скопировали данные и сделали последнее переименование.
Обновление будет выглядеть так:
Если Key - это столбец Identity, вам нужно использовать немного другой подход.
источник
Попробуйте использовать шардинг для географического распределения данных вашей базы данных. После этого вы сможете определить различные окна обслуживания для каждого географического местоположения, и время на обслуживание будет короче. Это также улучшит производительность. Вы можете узнать больше об этой статье. Не ждите, пока база данных станет больше.
Когда большие базы данных и пользователи подключены круглосуточно, необходимо использовать реорганизацию индекса и обновлять только те статистические данные, которые необходимо обновить (sp_updatestats), чтобы минимизировать время, необходимое для обслуживания, и влияние на пользователей.
Надеюсь это поможет.
источник