Firebird碎片整理吗?如果是这样,就像聚集索引一样?

时间:2013-10-16 15:13:06

标签: performance firebird clustered-index defragmentation mvcc

我在文档中看到了一些(字面上,只有少数几个)链接,并且没有说明与Firebird集群的事情,可以这样做。

然后,我在这个问题CLUSTER command for Firebird?上为月亮拍摄,但是回答者告诉我Firebird甚至根本没有聚集索引,所以现在我真的很困惑。

Firebird是否实际上对数据进行了排序?如果是这样,可以通过任何密钥订购,而不仅仅是主密钥,并且可以打开和关闭群集/碎片整理,以便它只在停机期间执行吗?

如果没有,这不是性能的打击,因为它会花费更长的时间将不同的行放在一起,这些行自然应该是彼此相邻的吗?

(DB noob)

MVCC

我发现Firebird基于MVCC,因此旧的数据实际上不会被覆盖,直到“扫描”。我非常喜欢这个!

同样,我找不到多少,但数据不会根据密钥进行碎片整理似乎真的很遗憾。

This表示数据库页面已经过碎片整理,但没有提供进一步的解释。

2 个答案:

答案 0 :(得分:10)

Firebird不会群集记录。它旨在避免需要群集的问题以及聚簇索引带来的碎片问题。索引和数据分别存储在不同类型的页面上。每个数据页面仅包含一个表中的数据。记录按插入顺序存储,提供或采用并发插入,这些插入通常位于不同的页面上。删除旧记录后,新记录将存储在其位置,因此新记录有时会与旧记录显示在同一页面上。

许多表使用人工主键,通常是升序,可能是数据库生成的序列或时间戳。这种做法导致记录按密钥顺序存储,但该顺序无法保证。也不是很有趣。当主键是人为的时,大多数返回相关记录组的查询都在二级索引上完成。由于二级索引上的查找需要遍历两个索引,因为二级索引仅提供主索引的密钥,必须遍历该索引才能查找数据。

在更大的碎片整理和空间使用问题上,Firebird会跟踪页面上的可用空间,以便在已删除记录的页面上插入新记录。如果页面变为完全空,则将重新分配。此空间管理在数据库运行时完成。如您所知,Firebird使用多版本并发控制,因此当更新或删除记录时,Firebird会创建新的记录版本,但保留旧版本。当提交更改之前运行的所有事务都已结束时,旧记录版本不再用于任何目的,Firebird将删除它。在许多应用程序中,旧版本在运行数据库的正常过程中被删除。当事务触及旧版本的记录时,Firebird会检查旧版本的状态,如果没有正在运行的事务可以读取它们,则将其删除。有一个名为“Sweep”的函数可以系统地删除不需要的旧记录版本。 Sweep可以与其他数据库活动同时运行,但最好在数据库负载较低时安排它。所以不,在你进行扫描之前不会删除任何内容。

致以最诚挚的问候,

安·哈里森

谁和Firebird以及它的前辈一起工作了很长时间

顺便说一句 - 作为第一个回答提及的人,Firebird确实在页面上留有空间,以便旧版本的记录与新版本保持在同一页面上。它不是空间的固定百分比,而是存储在页面上的每个记录16个字节,因此具有非常短记录的表的页面具有更多可用空间,而具有长记录的表具有更少。

答案 1 :(得分:2)

在恢复时,数据库页面已创建~70%已满(我记得,除非您指定gbak的-use_all_space开关),并且一次只执行一个表的恢复,根据需要将页面写入数据库文件的末尾。您可以想象一个可以将页面缩减到更少的情况。因此将数据整合在一起并“整理”它。

至于控制磁盘上的物理分组或进行在线碎片整理 - 在Firebird中没有。请记住,仅仅因为您需要访问页面并不意味着您的磁盘执行读取文件系统和数据库缓存可以避免它!