我已经看到了一些(字面意思,只有几个)链接,并且文档中没有任何关于使用 Firebird 进行集群的内容,它可以完成。
然后,我在这个问题 CLUSTER command for Firebird? 上大放异彩,但回答者告诉我 Firebird 甚至根本没有聚集索引,所以现在我真的很困惑。
Firebird 是否对数据进行物理排序?如果是这样,它是否可以按任何键排序,而不仅仅是主键,并且可以打开和关闭集群/碎片整理,以便仅在停机期间执行此操作?
如果没有,这不是对性能的影响,因为将自然应该彼此相邻的不同行放在一起需要更长的磁盘时间吗?
(数据库菜鸟)
MVCC
我发现 Firebird 基于 MVCC,所以旧数据实际上直到“扫描”才会被覆盖。我非常喜欢那个!
再一次,我找不到太多东西,但数据不会根据 key 进行碎片整理似乎真的很遗憾。
This 表示对数据库页面进行了碎片整理,但没有提供进一步的解释。
最佳答案
Firebird 不会对记录进行聚类。它旨在避免需要聚集的问题以及聚集索引带来的碎片问题。索引和数据分别存储在不同类型的页面上。每个数据页仅包含来自一个表的数据。记录按插入顺序存储,进行并发插入,通常在单独的页面上进行。当旧记录被删除时,新记录将被存储在它们的位置,因此新记录有时会与旧记录出现在同一页面上。
许多表使用人工主键,通常是升序,可能是数据库生成的序列或时间戳。这种做法导致记录按键顺序存储,但该顺序并不能得到保证。也不是很有趣。当主键是人工的时,大多数返回相关记录组的查询都是在二级索引上完成的。对于聚集的记录来说,这是一个性能损失,因为在二级索引上的查找需要遍历两个索引,因为二级索引只提供主索引的键,必须遍历主索引才能找到数据。
关于碎片整理和空间使用的更大问题,Firebird 会跟踪页面上的可用空间,因此将在已删除记录的页面上插入新记录。如果一个页面完全为空,它将被重新分配。这种空间管理是在数据库运行时完成的。如您所知,Firebird 使用多版本并发控制,因此当更新或删除记录时,Firebird 会创建一个新的记录版本,但保留旧版本。当在提交更改之前运行的所有事务都结束时,旧的记录版本不再有任何用途,Firebird 将删除它。在许多应用程序中,旧版本在运行数据库的正常过程中被删除。当事务接触旧版本的记录时,Firebird 会检查旧版本的状态,如果没有正在运行的事务可以读取它们,则将其删除。有一个名为“Sweep”的功能可以系统地删除不需要的旧记录版本。 Sweep 可以与其他数据库事件同时运行,但最好在数据库负载较低时安排它。所以不,在您运行扫描之前,没有任何内容被删除是不正确的。
此致,
安·哈里森
谁与 Firebird 及其前辈一起工作了很长时间
顺便说一句 - 正如第一个回答的人提到的那样,Firebird 确实在页面上留下了空间,以便旧版本的记录与新版本保持在同一页面上。它不是固定的空间百分比,而是每条记录 16 字节存储在页面上,因此记录非常短的表的页面有更多的可用空间,而记录长的表则更少。
关于performance - Firebird 会进行碎片整理吗?如果是这样,像聚集索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19407153/