Firebird дефрагментирует? Если это так, как кластерный индекс?
Я видел несколько (буквально только несколько) ссылок и ничего в документации, где говорится о кластеризации с Firebird, о том, что это можно сделать.
Затем я выстрелил на Луну по этому вопросу, команда CLUSTER для Firebird?, но ответчик сказал мне, что у Firebird даже нет кластерных индексов, так что теперь я в замешательстве.
Firebird ли физически упорядочивает данные? Если да, может ли он быть заказан любой клавишей, а не только первичной, и можно ли включать и выключать кластеризацию / дефрагментацию, чтобы она выполняла это только во время простоя?
Если нет, не является ли это ударом по производительности, поскольку на сборку разрозненных рядов, которые, естественно, должны располагаться рядом друг с другом, уйдет больше времени?
(БД нуб)
MVCC
Я обнаружил, что Firebird основан на MVCC, поэтому старые данные на самом деле не перезаписываются до "развертки". Мне это очень нравится!
Опять же, я не могу найти много, но кажется настоящим позором, что данные не будут дефрагментированы в соответствии с ключом.
Это говорит о том, что страницы базы данных дефрагментированы, но не дает дальнейших объяснений.
2 ответа
Firebird не группирует записи. Он был разработан, чтобы избежать проблем, которые требуют кластеризации, и проблем фрагментации, которые приходят с кластерными индексами. Индексы и данные хранятся отдельно, на разных типах страниц. Каждая страница данных содержит данные только из одной таблицы. Записи хранятся в том порядке, в котором они были вставлены, даны или приняты одновременно, которые обычно размещаются на отдельных страницах. Когда старые записи удаляются, новые записи будут храниться на их месте, поэтому новые записи иногда появляются на той же странице, что и старые.
Многие таблицы используют искусственный первичный ключ, обычно восходящий, который может быть последовательностью, сгенерированной базой данных, или временной меткой. Эта практика приводит к тому, что записи хранятся в ключевом порядке, но этот порядок ни в коем случае не гарантируется. И это не очень интересно. Когда первичный ключ является искусственным, большинство запросов, которые возвращают группы связанных записей, выполняются по вторичным индексам. Это снижение производительности для кластеризованных записей, так как для поиска вторичных индексов требуется обход двух индексов, поскольку вторичный индекс предоставляет только ключ к первичному индексу, который необходимо пройти, чтобы найти данные.
Что касается более широкой проблемы дефрагментации и использования пространства, Firebird отслеживает свободное место на страницах, поэтому новые записи будут вставляться на страницы, для которых записи были удалены. Если страница станет полностью пустой, она будет перераспределена. Это управление пространством выполняется во время работы базы данных. Как вы знаете, Firebird использует Multi-Version Concurrency Control, поэтому, когда запись обновляется или удаляется, Firebird создает новую версию записи, но сохраняет старую версию. Когда все транзакции, которые выполнялись до принятия изменения, закончились, старая версия записи больше не служит никаким целям, и Firebird удалит ее. Во многих приложениях старые версии удаляются в ходе обычной работы базы данных. Когда транзакция касается записи со старыми версиями, Firebird проверяет состояние старых версий и удаляет их, если ни одна из запущенных транзакций не может их прочитать. Существует функция под названием "Sweep", которая систематически удаляет ненужные старые версии записей. Развертка может выполняться одновременно с другими действиями с базой данных, хотя лучше планировать ее при низкой загрузке базы данных. Так что нет, это неправда, что ничего не удаляется до тех пор, пока вы не выполните проверку.
С наилучшими пожеланиями,
Энн Харрисон
кто работал с Firebird и его предшественниками в течение долгого времени
Кстати, как первый, кто ответил, упомянул, что Firebird оставляет место на страницах, так что старая версия записи остается на той же странице, что и более новая версия. Это не фиксированный процент пространства, а 16 байтов на запись, хранящуюся на странице, поэтому страницы таблиц с очень короткими записями имеют больше свободного места, а таблицы с длинными записями - меньше.
При восстановлении страницы базы данных создаются на 70% заполненными (насколько я помню, если вы не укажете ключ gbak -use_all_space), и восстановление выполняется по одной таблице за раз, записывая страницы в конец файла базы данных по мере необходимости. Вы можете представить себе сценарий, в котором страницы могут быть сжаты до гораздо меньшего размера. Следовательно, объединяя данные и "дефрагментируя" их.
Что касается контроля физической группировки на диске или проведения онлайн-дефрагментации - в Firebird их нет. Помните, что если вам нужен доступ к странице, это не означает, что ваш диск выполняет чтение - файловая система, а кэш базы данных может этого избежать!