Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
Селективность уникального индекса равна I. Все неуникальные индексы имеют значение меньше 1. Селективность (s) вычисляется как [56]
s = n / количество строк в таблице
где n- количество различных экземпляров значения индекса в таблице. Чем меньше количество отличающихся экземпляров, тем меньше селективность. Индексы с более высокой селективностью выполняются лучше, чем индексы с низкой селективностью.
56
Изложенное понятие селективности обратно числам, реально используемым оптимизатором. Оптимизатор берет информацию о селективности из столбца RDB$STMTSTICS
– Прим. науч. ред.
Оптимизатор Firebird отыскивает коэффициент для вычисления селективности при первом обращении к таблице и сохраняет его в памяти для использования при вычислении планов при последующих запросах к этой таблице. Со временем вычисленные коэффициенты для часто изменяемых таблиц становятся устаревшими, возможно влияя на выбор оптимизатором индекса в экстремальных случаях.
Пересчет селективности индекса изменяет статистический множитель, хранящийся в системных таблицах. Оптимизатор читает его один раз при выборе плана- он не является особенно значимым для его выбора. Часто большие операции DML не обязательно повреждают распределение различных значений ключа индекса. Если индексирование разумно, то "демография" распределения значений может изменяться очень незначительно.
Знание наиболее правильной селективности индекса имеет большое значение для разработчика. Это дает основу для определения полезности индекса.
Если эффективность плана со временем снижается по причине большого количества добавлений или изменений ключевого столбца (столбцов), которые изменяют распределение значений ключа, быстродействие запросов может постепенно снижаться. Любой индекс, чья селективность со временем резко падает, должен быть удален, потому что он влияет на производительность.
Работа с неконтролируемым индексом, который ухудшается по мере роста таблицы до того, как он начинает влиять на планы запросов, является важной частью настрой- ки базы данных. При этом большинство критических эффектов использования индекса с фактически низкой селективностью практически не влияют на оптимизатор и оказывают сильное воздействие на геометрию индекса [57] .
Для индексов Firebird создает двоичное дерево. Он хранит эти структуры на индексных страницах, которые выделяются только для хранения индексных деревьев. Каждое значение в сегменте индекса имеет собственный узел за пределами корня дерева. Когда в индекс добавляется новая запись, она или помещается в новый узел, если ее значение не существует в индексе, или помещается в начало стека существующих дубликатов значений.
57
На оптимизатор в основном влияет то, что с течением времени если индекс меняется (меняются индексируемые данные), то статистика индекса остается неизменной, т. к. она меняется только вручную вызовом оператора SET STATISTICS. Поэтому вместо рекомендуемого здесь периодического пересоздания индексов лучше озаботиться регулярным пересчетом статистики индексов.
– Прим. науч. ред.
Рис. 18.2 иллюстрирует этот двоичный механизм в простейшей форме
Когда появляются дублирующие значения, они помещаются в первый узел в начало "цепи" других дубликатов - это то, что происходит со значением ghi на нашей диаграмме. Такая структура называется цепочкой дубликатов.
Цепочка
58
В этом месте разговор идет со слов Ann Harrison, "матери InterBase".
Затраты на все такие "перемешивания" и "взбалтывания" никогда не связаны с транзакцией, которая удаляет или изменяет все строки в таблице. Изменение значения ключа или его удаление влияет на индекс позже, когда старые версии будут включены в процесс сборки мусора. Затраты проявятся для следующей транзакции, обращающейся к этим строкам и выполняющейся после завершения всех транзакций, которые были активны, когда выполнялось изменение или удаление [59] .
59
Сборка мусора в больших цепочках дубликатов ключей значительно ускорена в Firebird 2.0. Собственно, в Firebird 2.0 изменена структура индексов.
– Прим. науч. ред.
Стандартная поставка Firebird содержит множество инструментов и приемов для получения состояния индексов и поддержания их в хорошей форме.
* Для получения значения селективности и других значимых характеристик индексов используйте анализатор статистики данных gstat. Позже в этой главе мы рассмотрим, как gstat может рассказать вам о ваших индексах.
* Инструментом для пересчета селективности индекса является оператор SET STATISTICS (обсуждаемый в следующем разделе), SET STATISTICS не пересоздает индекс.
* Лучшей из всех инструментов для чистки индексов является утилита резервного копирования и восстановления gbak. Восстановление базы данных из самой последней резервной копии пересоздает все индексы и заново вычисляет их селективность.
В некоторых таблицах количество дублирующих значений в индексированных столбцах может радикально увеличиваться или уменьшаться как результат относительной "популярности" отдельных значений в индексе по сравнению с другими кандидатами в значения. Например, индексы по датам в системе продаж могут иметь тенденцию становиться менее селективными при резком увеличении деловой активности.
Периодическое вычисление селективности индекса может увеличить производительность индексов, которые являются субъектами значительных изменений в распределении различных значений.
Оператор SET STATISTICS заново вычисляет селективность индекса. Этот оператор может быть выполнен в интерактивной сессии isql или запущен в приложении ESQL. Для выполнения оператора SET STATISTICS вы должны быть соединены с базой данных как пользователь, создавший индекс, как пользователь SYSDBA или (в POSIX) как пользователь с привилегиями операционной системы root.
Синтаксис:
SET STATISTICS INDEX ИМЯ;
Следующий оператор заново вычисляет селективность индекса в базе данных employee.gdb:
SET STATISTICS INDEX MINSALX;
Сам по себе оператор SET STATISTICS не решает текущие проблемы, являющиеся результатом предыдущего использования индекса, которые связаны с устаревшей статистикой селективности, потому что он не пересоздает индекс.
! ! !
СОВЕТ. Для пересоздания индекса используйте ALTER INDEX, или удалите и заново создайте его, или восстановите базу данных с резервной копии.