4

我正在使用 Firebird 2.5.1 Embedded。我已经按照惯例清空了将近 200k 行的表:

delete from SZAFKI

这是输出,看它需要 16 秒,这是不可接受的。

Preparing query: delete from SZAFKI
Prepare time: 0.010s
PLAN (SZAFKI NATURAL)

Executing...
Done.
3973416 fetches, 1030917 marks, 116515 reads, 116434 writes.
0 inserts, 0 updates, 182658 deletes, 27 index, 182658 seq.
Delta memory: -19688 bytes.
SZAFKI: 182658 deletes. 
182658 rows affected directly.
Total execution time: 16.729s
Script execution finished.

Firebird 没有 TRUNCATE 关键字。由于查询使用 PLAN NATURAL,我尝试手动计划查询,如下所示:

delete from szafki PLAN (SZAFKI INDEX (SZAFKI_PK))

但火鸟说“SZAFKI_PK 不能在指定的计划中使用”(它是一个主键)问题是我如何有效地清空表?无法删除和重新创建。

4

3 回答 3

7

根据我的评论回答

您可以尝试的一个技巧是使用DELETE FROM SZAFKI WHERE ID > 0(假设ID是 1 或更高)。这将强制 Firebird 使用主键索引查找行。

我最初的假设是这会比未索引的删除更糟糕。未索引的删除将对表的所有数据页进行顺序扫描并删除行(即:创建一个新的记录版本,它是已删除的存根记录)。当您使用索引时,它将按索引顺序查找行,这将导致随机遍历数据页(假设由于插入、删除和更新导致的大量记录版本导致数据中的高度碎片化)。我曾预计这会更慢,但可能会导致 Firebird 只需要读取相关数据页(具有与事务相关的记录版本)而不是表的所有数据页。

于 2012-12-15T09:17:49.057 回答
2

不幸的是,没有快速的方法可以使用当前的 Firebird 版本对整个(大)表进行大规模删除。当“删除的内容”被垃圾收集时,您可能会期待更高的延迟(在提交删除后在表中运行 select *,您会看到)。您可以在删除之前尝试停用该表中的索引,看看是否有帮助。如果您将表用作某种临时存储,我建议您使用 GTT 功能。

于 2012-12-13T16:25:22.390 回答
0

在 FireBird表中快速删除所有数据的最快也是唯一的方法-删除并再次创建表。至少对于目前的官方版本 2.5.X 。FireBird 3.0 的路线图中没有截断运算符,测试版已经出,所以很可能在 3.0 中也没有截断。

此外,您可以使用运算符RECREATE - 与 create 相同的语法。如果表存在,RECRATE 删除它,然后创建新表。如果表不存在,则重新创建只是创建它。

 RECREATE TABLE Table1 (
   ID    INTEGER,
   NAME  VARCHAR(20),
   DATE  DATE,
   T     TIME
 );
于 2013-12-12T08:11:41.580 回答