Firebird是否需要手动重建索引?

时间:2009-05-19 11:38:10

标签: firebird

我同时使用Firebird嵌入式和Firebird服务器,并且我不时需要使用如下过程重新索引表:

CREATE PROCEDURE MAINTENANCE_SELECTIVITY 
ASDECLARE VARIABLE S VARCHAR(200);
BEGIN
FOR select RDB$INDEX_NAME FROM RDB$INDICES INTO :S DO
BEGIN
S = 'SET statistics INDEX ' || s || ';';
EXECUTE STATEMENT :s;
END
SUSPEND;
END

我认为使用嵌入式这是正常的,但是真的需要使用服务器吗?有没有办法将服务器配置为在需要时或定期自动执行?

3 个答案:

答案 0 :(得分:20)

首先,让我指出我不是Firebird专家,所以我在回答SQL Server的工作原理。

在这种情况下,答案是肯定的,不是。

索引当然是在SQL Server上更新的,因为如果插入一个新行,该表的所有索引都将包含该行,因此将找到它。所以基本上,你不需要继续重新索引该部分的表来工作。那是“不”的一部分。

然而,问题不在于索引,而在于统计数据。你说你需要重新索引表格,但是你会显示操纵统计数据的代码,这就是我回答的原因。

简短的回答是,随着时间的推移,统计数据会逐渐失控。它们可能不会恶化到无法使用的程度,但是当它们重新创建/重新计算它们时,它们会从它们所处的完美水平下降。这是“是”部分。

陈旧统计数据的主要问题是,如果索引中键的分布发生巨大变化,统计信息可能不会立即选择,因此查询优化器将根据旧的陈旧情况选择错误的索引,它掌握的统计数据。

例如,假设您的某个索引的统计信息表明密钥在值空间的一端聚集在一起(例如,int-column有很多0和1)。然后,您插入许多行,其值包含使该索引包含遍布整个频谱的值。

如果您现在使用来自另一个表的连接执行查询,对具有此索引的表的选择性较低的列(也有很多0和1),查询优化器可能会推断出该索引是好的,因为它将获取将同时使用的许多行(它们位于同一数据页上)。

然而,由于数据已经改变,它会跳过索引以找到相关的部分,因此毕竟不是那么好。

重新计算统计信息后,查询优化器可能会发现此索引对于此查询而言是次优的,而是选择另一个索引,这更适合。

基本上,如果数据不断变化,您需要定期重新计算统计数据。如果您的数据很少发生变化,您可能不需要经常这样做,但我仍然会添加一些维护工作,但这样做会有规律性。

至于是否有可能要求Firebird独自完成它,那么我再次,我在薄冰上,但我怀疑有。在SQL Server中,您可以按计划设置执行此操作的维护作业,至少您应该能够从Windows计划程序启动批处理文件以执行类似的操作。

答案 1 :(得分:7)

这不重新索引,它重新计算索引的权重,优化程序使用它来选择最佳索引。除非索引大小发生很大变化,否则您不需要这样做。如果在添加数据之前创建索引,则需要重新计算。

嵌入式和服务器应具有与流程模型完全相同的功能。

答案 2 :(得分:2)

我想为更新的firebird更新这个答案。这是更新的dsql。

SET TERM ^ ;
CREATE OR ALTER PROCEDURE NEW_PROCEDURE 
AS
DECLARE VARIABLE S VARCHAR(300);
begin
  FOR select  'SET statistics INDEX ' || RDB$INDEX_NAME || ';' 
  FROM RDB$INDICES 
  WHERE RDB$INDEX_NAME <> 'PRIMARY' INTO :S 
  DO BEGIN
     EXECUTE STATEMENT :s;
  END
end^
SET TERM ; ^

GRANT EXECUTE ON PROCEDURE NEW_PROCEDURE TO SYSDBA;