Fill factor

02.08.21

База данных - HighLoad оптимизация

От переводчика: Публикация составлена по материалам BrentOzar.com (Brent Ozar).

5 Things About Fillfactor (Kendra Little)

Несколько статей на близкие темы.

Does low fill factor affect SELECT performance? (Tara Kizer)

Does index fill factor affect fragmentation? (Erik Darling)

Good Reasons to Rebuild or Reorganize Indexes (Erik Darling)

 

5 фактов о Fillfactor (Кендра Литтл)

 

Краткое введение: что такое fillfactor и как он устанавливается?

“Fillfactor” - это параметр для индексов в SQL Server. При создании или перестроении индекса вы можете указать SQL Server, какой процент каждой страницы данных объемом 8 КБ, используемой на “конечном” уровне индекса, необходимо заполнить.

Другими словами, если при перестройке кластеризованного индекса вы установите коэффициент заполнения 90%, SQL Server попытается оставить 10% каждой конечной страницы пустыми.

По умолчанию SQL Server использует 100% фактор заполнения и пытается заполнить все страницы в индексах до предела. Значения 0 и 100 – синонимы.

 

Существует два способа установки fillfactor в SQL Server

На уровне экземпляра SQL Server с использованием параметра sys.configuration для коэффициента заполнения. (Я не рекомендую использовать эту опцию по причинам, которые я опишу ниже.)

На уровне отдельного индекса, указав fillfactor при создании или перестроении индекса.

Задания по обслуживанию индексов иногда автоматизируют второй из этих вариантов. Если вы используете хранимую процедуру обслуживания индекса, скачанную с Интернета, возможно, вы устанавливаете fillfactor, не осознавая этого.

 

Почему люди любят устанавливать fillfactor?

Администраторы баз данных и разработчики часто считают, что снижение коэффициента заполнения повышает производительность за счет уменьшения разбиения страниц. Они либо слишком сильно понижают коэффициент заполнения для некоторых индексов, либо применяют изменение коэффициента заполнения ко всем индексам.

Коэффициент заполнения по умолчанию 100% не всегда хорош. Если я заполню свои страницы до предела, а затем мне нужно будет вставить строку на эту страницу, она не поместится. Чтобы данные соответствовали и сохраняли логическую структуру индекса, SQL Server придется выполнить множество сложных действий (избыточное разделение страниц), в том числе:

  • Добавить новую страницу

  • Перенести примерно половину данных на новую страницу

  • Установить недействительными перенесенные данные на старой странице

  • Обновить указатели ссылок на страницы на существующих страницах, чтобы указать на новую страницу

Это генерирует записи журнала и вызывает дополнительный ввод-вывод. И да, если у вас это часто случается, вы можете немного снизить коэффициент заполнения в этом индексе, чтобы это происходило реже.

 

На что влияет fillfactor?

Вот в чем дело: наличие большого количества пустого пространства на ваших страницах данных ТАКЖЕ негативно сказывается на производительности. Ваши данные более распределены, поэтому вам, вероятно, придется читать больше страниц в памяти. Вы тратите место в кэше, которое просто пустует. Это не только не потрясающе, во многих случаях это может быть УЖАСНО.

Это особенно расточительно, потому что не все индексы подвержены избыточным разделениям страниц. Допустим, у меня есть кластеризованный индекс с увеличивающимся значением идентификатора INT или BIGINT. Я вставляю множество новых строк, и значения редко обновляются или удаляются. В этом случае я могу заполнить свои страницы очень полно, потому что я всегда помещаю новые строки в конец индекса. Добавление этих новых страниц не является избыточным разбиением страниц, хотя, к сожалению, они учитываются в счетчике производительности “разбиение страниц/сек”, что делает очень сложным поиск только избыточных разбиений.

Я часто нахожу, что люди устанавливают значение коэффициента заполнения 80 или ниже для всех индексов в базе данных. Это может привести к потере многих Гб места на диске и в памяти. Это потраченное впустую пространство приводит к дополнительным перемещениям в хранилище, и все это снижает производительность ваших запросов.

 

Рекомендации по настройке фактора заполнения

Вот несколько простых советов о том, как безопасно установить fillfactor:

Не устанавливайте общесистемное значение для fillfactor. Очень маловероятно, что это поможет вашей работе больше, чем повредит.

Получите хорошее решение для обслуживания индексов, которое проверяет фрагментацию индексов и действует только на индексы, которые достаточно сильно фрагментированы. Запишите решение в таблицу. Ищите индексы, которые часто фрагментированы. Рассмотрите возможность постепенного снижения коэффициента заполнения для этих отдельных индексов, используя запланированное изменение для перестройки индекса. Когда вы впервые снизите коэффициент заполнения, подумайте о том, чтобы просто перейти на 95 и переоценить индекс после недели или двух повторного обслуживания. (В зависимости от вашей версии и выпуска SQL Server, перестройку может потребоваться выполнить в автономном режиме. Реорганизация не может быть использована для установки нового фактора заполнения.)

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

 

Итак - 5 фактов о fillfactor

 

1) документация Microsoft предупреждает:

Самое болезненное в поиске плохих параметров наполнения заключается в том, что команда Microsoft пыталась предупредить людей о том, как плохие параметры наполнения могут повлиять на производительность. К сожалению, большинство людей, похоже, не замечают этого предупреждения.

Ознакомьтесь с этой цитатой: “Значение коэффициента заполнения 50 может привести к снижению производительности чтения базы данных в два раза“.

Это ведь совершенно ясно, верно? Поэтому, если я установлю коэффициент заполнения 70 (когда он мне не нужен), я рискую снизить производительность на 30%. Это тоже звучит не очень хорошо. Из-за этого хрупкого баланса следуйте приведенным выше рекомендациям.

2) fillfactor не применяется к кучам

Параметр fillfactor применяется только к индексам, а не ко всем таблицам. Если у вас есть таблица, в которой нет кластеризованного индекса, в SQL Server она называется “кучей”. Кучи странны в нескольких отношениях. Один из этих способов заключается в том, что фактор заполнения не применяется– даже тот фактор заполнения, который вы установили на уровне экземпляра. (Разделение страниц тоже работает по-разному, но это не веская причина для создания кучи.)

3) fillfactor не влияет на новые страницы, вставленные в конце индекса

SQL Server использует fillfactor только при создании, перестройке или реорганизации индекса. Он не использует fillfactor, если он выделяет новую страницу в конце индекса.

Давайте рассмотрим пример кластеризованного индекса, где ключом снова является увеличивающееся значение идентификатора INT. Мы просто вставляем строки, и это добавляет новые страницы в конце индекса. Индекс был создан с коэффициентом заполнения 70% (что, возможно, было не очень хорошей идеей). По мере добавления новых страниц эти страницы заполняются как можно больше– вероятно, более 70%. (Это зависит от размера строки и от того, сколько строк может поместиться на странице.)

4) fillfactor не применяется к LOB pages

Фактор заполнения применяется к страницам данных в строке. При создании таблицы, в зависимости от типов данных, у вас есть варианты, когда некоторые большие типы будут храниться в строке или вне строки. Если данные не хранятся в строке, параметры fillfactor не применяются к этим специальным страницам.

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

5) Кто-то, возможно, изменил fillfactor без вашего ведома

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

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

 

Заключение оригинальной статьи

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

Как проверить свои настройки сегодня

Наш бесплатный инструмент sp_BlitzIndex ищет все виды безумия в ваших индексах на уровне базы данных. Он будет просматривать ваши метаданные и предупреждать вас о низких значениях коэффициента заполнения, а также позволит вам точно знать, насколько выросли эти индексы. Проверьте это сегодня.

 

От переводчика

Лично меня статья полностью убедила: fillfactor должен быть по умолчанию 100%. В комментариях к статье указан источник, в котором есть рекомендация устанавливать fillfactor 80%. Это редкий частный случай. Можно ли выиграть, уменьшая значение fillfactor ?

В базе данных TEST_UT_VN создадим таблицу и кластерный индекс

USE [TEST_UT_VN]
GO
CREATE TABLE [dbo].[TestMe]
(               [Column1] [uniqueidentifier] NOT NULL,
                [Column2] [nchar](400) NOT NULL
) ON [PRIMARY]
CREATE CLUSTERED INDEX [ClusteredIndex] ON [dbo].[TestMe]
(              [Column1] ASC,
               [Column2] ASC
) ON [PRIMARY]

Здесь значения Столбец1 – не являются монотонно возрастающими, а Столбец2 – занимает 800 байт, это близко к максимальному размеру индекса 900 байт. Страница СУБД размером 8 Кб содержит 9 строк. Соответственно, при вставке строк, split page происходит достаточно часто. На моем сервере скрипт работает 7 секунд, примерно 7000 запросов (Insert)  в секунду, около 600 page split в секунду.

Будем выполнять скрипт, изменяя значение fillfactor:

USE [TEST_UT_VN];  
GO
DECLARE @Counter as integer;
SET @Counter = 1;
ALTER INDEX ALL ON [dbo].[TestMe] REBUILD WITH (FILLFACTOR = 100);
DBCC SQLPERF ('sys.dm_os_wait_stats', CLEAR);  
WHILE @Counter < 50000
BEGIN  
   SET @Counter = @Counter + 1;
   INSERT INTO [dbo].[TestMe] VALUES (NEWID(), '');
END  
SELECT TOP 5 * FROM sys.dm_os_wait_stats ORDER BY wait_time_ms DESC

 

 

Удалось обнаружить корреляцию между показателями fillfactor и LOGMGR_QUEUE:

Номер опыта

FILLFACTOR

LOGMGR_QUEUE

task_count

11

100

32286

50257

12

80

26320

50229

13

100

34433

50146

14

80

25634

50091

15

100

39293

50210

16

80

26700

50148

Опыты показывают, что ожидание типа LOGMGR_QUEUE может зависеть от fillfactor на 20-40 процентов. Если у вас этот тип ожидания доминирует, то можно пробовать изменить настройки fillfactor. Во всех других случаях лучше значение по умолчанию=100%.

Переводчик выражает благодарность Виктору Богачеву – автору и ведущему «Подготовка к 1С:Эксперту по технологическим вопросам. Основной курс» за спонсорскую помощь.

LOGMGR_QUEUE fillfactor

См. также

HighLoad оптимизация Технологический журнал Системный администратор Программист Бесплатно (free)

Обсудим поиск и разбор причин длительных серверных вызовов CALL, SCALL.

24.06.2024    5170    ivanov660    12    

56

HighLoad оптимизация Программист Платформа 1С v8.3 Бесплатно (free)

Метод очень медленно работает, когда параметр приемник содержит намного меньше свойств, чем источник.

06.06.2024    9291    Evg-Lylyk    61    

44

HighLoad оптимизация Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Анализ простого плана запроса. Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы.

13.03.2024    5114    spyke    28    

49

HighLoad оптимизация Программист Платформа 1С v8.3 Бесплатно (free)

Оказывается, в типовых конфигурациях 1С есть, что улучшить!

13.03.2024    7597    vasilev2015    20    

42

HighLoad оптимизация Инструменты администратора БД Системный администратор Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Обработка для простого и удобного анализа настроек, нагрузки и проблем с SQL сервером с упором на использование оного для 1С. Анализ текущих запросов на sql, ожиданий, конвертация запроса в 1С и рекомендации, где может тормозить.

2 стартмани

15.02.2024    12463    241    ZAOSTG    82    

115

HighLoad оптимизация Системный администратор Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Принимать, хранить и анализировать показания счетчиков (метрики) в базе 1С? Почему бы нет? Но это решение быстро привело к проблемам с производительностью при попытках построить какую-то более-менее сложную аналитику. Переход на PostgresSQL только временно решил проблему, т.к. количество записей уже исчислялось десятками миллионов и что-то сложное вычислить на таких объемах за разумное время становилось все сложнее. Кое-что уже практически невозможно. А что будет с производительностью через пару лет - представить страшно. Надо что-то предпринимать! В этой статье поделюсь своим первым опытом применения СУБД Clickhouse от Яндекс. Как работает, что может, как на нее планирую (если планирую) переходить, сравнение скорости работы, оценка производительности через пару лет, пример работы из 1С. Все это приправлено текстами запросов, кодом, алгоритмами выполненных действий и преподнесено вам для ознакомления в этой статье.

1 стартмани

24.01.2024    5692    glassman    18    

40

HighLoad оптимизация Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Встал вопрос: как быстро удалить строки из ТЗ? Рассмотрел пять вариантов реализации этой задачи. Сравнил их друг с другом на разных объёмах данных с разным процентом удаляемых строк. Также сравнил с выгрузкой с отбором по структуре.

09.01.2024    14105    doom2good    49    

71
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ildary 21 02.08.21 10:23 Сейчас в теме
Спасибо за ещё одну полезную статью!
2. Yashazz 4791 02.08.21 19:04 Сейчас в теме
Вообще, что я в своё время понял из курса Эксперта и, особенно, из экзамена по нему: не бывает единых универсальных рецептов, советов на все случаи жизни и всяких ультима-туле. Каждый сложный случай индивидуален, поэтому подходить следует, вооружившись знаниями и лишь отчасти практиками и опытом других - свой опыт неповторим и в разы более ценен. Я когда Богачёву сдавал Эксперта, сижу, говорю всё по книжке Филиппова, ровно, гладко, а у него на лице явная несдача проступает. И только когда я стал ему рассказывать настоящие реальные случаи из практики, он оживился и вообще сменил гнев на милость.

Спасибо за статью. Дальше только "бой покажет".
3. user1593937 03.08.21 10:52 Сейчас в теме
это ожидание само по себе не является проблемой.
https://www.sqlshack.com/sql-server-wait-type-logmgr-queue/
так то.
4. vasilev2015 2723 03.08.21 13:13 Сейчас в теме
(3) Ниже перевод фрагмента https://www.sqlshack.com/sql-server-wait-type-logmgr-queue/

Предлагаемые решения

Безопасно игнорировать, если LOGBUFFER and WRITELOG невелики

1. Удалите курсор или итеративные процедуры, вносящие множество небольших изменений. Замените их пакетными модификациями
2. Посмотрите, подходит ли параметр базы данных Delayed Durability для системы баз данных
3. Отключите все неиспользуемые индексы. Это уменьшит количество записей во время изменения данных
4. Убедитесь, что коэффициенты заполнения индекса установлены соответствующим образом, чтобы избежать разделения страниц.
5. Индексы, которые часто меняются, должны иметь более низкий коэффициент заполнения

Это ожидание не проблема, но решение содержит 5 (пять !) пунктов.
Пункты 4,5 совпадают с тем, что я сделал в статье. Это хороший знак.

Спасибо за интересный комментарий.
5. asved.ru 36 06.08.21 08:42 Сейчас в теме
Получите хорошее решение для обслуживания индексов, которое проверяет фрагментацию индексов и действует только на индексы, которые достаточно сильно фрагментированы. Запишите решение в таблицу.


Промт детектед.

Очевидно, речь идет о табличном журналировании степени фрагментации индексов. Действительно, если часто делить страницы, то фрагментация будет расти, т.к. новые страницы выделяются где попало.
Однако частое добавление страниц при инкрементном росте индекса приводит к тем же самым результатам.

В контексте 1С кажется разумным проверять запись в наиболее фрагментированные индексы с прикладной точки зрения: насколько часто осуществляются операции, пишущие не в конец индекса, и насколько это адекватно с точки зрения платформы и бизнес-потребностей.
6. vasilev2015 2723 06.08.21 09:04 Сейчас в теме
(5) Авторы оригинальной статьи продвигают Blitz - популярное решение.
Но они не знали, что в любимой 1С размер индексов может быть больше, чем основных таблиц :-)
Оставьте свое сообщение