performance - Firebird 会进行碎片整理吗?如果是这样,像聚集索引?

标签 performance firebird clustered-index defragmentation mvcc

我已经看到了一些(字面意思,只有几个)链接,并且文档中没有任何关于使用 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/

相关文章:

mysql - 我如何确定这是哪种类型的数据库?

sql-server - SQL Server中主键(簇)和簇唯一索引的区别

sql - SQL Server默认创建非聚集索引

java - 限制java应用程序的内存和cpu使用

python - 有没有办法使用python进一步缩短稀疏解决时间?

multithreading - 在 IIS 下增加 .NET Remoting 应用程序的并发请求

python - 为什么一种算法比另一种算法快(用链表添加数字)

java - Firebird 和不同版本的 JVM

c# - 偏移量 1049 处的无效请求 BLR - 函数 ROUNDDEC 未定义

sql - 如何删除聚集属性但保留表中的主键。 SQL Server 2005