database – 表的维护:在截断和重新填充后,是否需要REINDEX表?

前端之家收集整理的这篇文章主要介绍了database – 表的维护:在截断和重新填充后,是否需要REINDEX表?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个表,其中有大约200万行我们用于分析的事务数据.每周我们用新数据重新加载它,所以我们一直使用TRUNCATE清除它然后插入新行.

桌子上有几个索引.如果我不删除并重新创建索引,我是否需要在每次截断和重新填充后重新索引,或者这是不必要的?我应该在TRUNCATE之后运行VACUUM,还是不必要?

不,你通常不需要在TRUNCATE之后重新索引 – 如果你这样做,你最好放弃索引,加载数据,然后在最后重新创建索引.

它有点类似于this answer about cluster – Pg在TRUNCATE期间自动丢弃索引,然后在插入数据时逐步重建它,因此在TRUNCATE之前没有保持索引膨胀.

如果删除索引,截断,插入数据和重新创建索引,则可能会获得更紧凑和高效的索引.他们肯定会更快建立.一旦构建,索引性能的差异就不足以保证大多数应用程序仅使用b-tree索引的额外工作,但填充表所需的时间差异非常值得.如果您正在使用GiST或(特别是)GIN,最好删除索引并在最后重新创建.

如果这样做很方便,请删除索引并在最后添加它们,如果这对您不实用,请不要太担心.

对于我测试中的常规b树,增量创建的复合索引为3720kb,而一次性创建的索引为2208kb.构建时间为164ms(插入)347ms(索引)对比742ms(插入索引).这种差异很大,但不足以成为一个巨大的问题,除非你做大规模的DW.插入索引运行后,REINDEX再花了342ms.看到

因此,@TomTom是正确的(不足为奇),因为如果方便的话,可以放弃并重新创建索引,就像你为OLAP工作大量填充表一样.

但是,重建索引很可能是错误的答案,因为这意味着你要做一大堆昂贵的工作来创建一个你扔掉的索引.删除索引并重新创建它而不是重新索引.

演示会:

regress=# -- Create,populate,then create indexes:
regress=# CREATE TABLE demo (someint integer,sometext text);
CREATE TABLE
regress=# \timing on
regress=# INSERT INTO demo (someint,sometext)
SELECT x,(x%100)::text
FROM generate_series(1,100000) x;
INSERT 0 100000
Time: 164.678 ms
regress=# CREATE INDEX composite_idx ON demo(sometext,someint);
CREATE INDEX
Time: 347.958 ms
regress=# SELECT pg_size_pretty(pg_indexes_size('demo'::regclass));
 pg_size_pretty 
----------------
 2208 kB
(1 row)
regress=# -- Total time: 347.958+164.678=512.636ms,index size 2208kB

regress=# -- Now,with truncate and insert:
regress=# TRUNCATE TABLE demo;
TRUNCATE TABLE
regress=# INSERT INTO demo (someint,100000) x;
INSERT 0 100000
Time: 742.813 ms
regress=# SELECT pg_size_pretty(pg_indexes_size('demo'::regclass));
 pg_size_pretty 
----------------
 3720 kB
(1 row)
regress=# -- Total time 742ms,index size 3720kB
regress=# -- Difference: about 44% time increase,about 68% index size increase.
regress=# -- Big-ish,but whether you care depends on your application. Now:

regress=# REINDEX INDEX composite_idx ;
REINDEX
Time: 342.283 ms
regress=# SELECT pg_size_pretty(pg_indexes_size('demo'::regclass));
 pg_size_pretty 
----------------
 2208 kB
(1 row)

regress=# -- Index is back to same size,but total time for insert with progressive
regress=# -- index build plus reindex at the end us up to 1084.283,twice as long as
regress=# -- dropping the indexes,inserting the data,and re-creating the indexes took.

所以:

>对于OLAP,删除索引,插入,重新创建索引.
>对于OLTP,您可能只想坚持使用渐进式索引构建.考虑索引上的非100%fillfactor以降低插入成本.
>避免插入渐进式索引构建然后重新索引,这是两个世界中最糟糕的.

当然,此测试中使用的尺寸是玩具桌尺寸,因此您应该对现实世界数据和索引的样本重复此测试,以便深入了解它对您的影响程度.我以比上述更大的比例因子100重复这些测试,并且如果逐渐构建,则始终发现索引几乎是大小的两倍,尽管相对构建时间差异实际上在这个特定测试中下降.

所以:使用您的数据和架构进行测试.

猜你在找的Postgre SQL相关文章