前言

fillfactor

表的填充因子是一个介于 10 和 100 之间的百分数。100是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本(MVCC)放置在其它后面的页上更高效。对于一个从不更新或很少更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,较小的填充因子执行效率更高。该参数对toast表不生效。

索引的填充因子也是一个百分数,它决定索引方法将尝试填充索引页面的充满程度。对于B-tree,在初始的索引构建过程中,叶子页面会被填充至该百分数,B-tree默认的填充因子是90,可以设置为10-100的任何整数值。如果表是静态的,那么填充因子100是最好的,这样索引占用空间最小。对于更新频繁的表,设置较小的值可以最小化索引分裂。

测试环境使用版本为V8R6,少部分内容在R3上进行了测试。

测试

--创建表test1并设置fillfactor=100
test=# create table test1(n_id int,cc varchar(300)) with (fillfactor=100);
CREATE TABLE
--创建表test2并书设置fillfactor=70
test=# create table test2(n_id int,cc varchar(300)) with (fillfactor=70);
CREATE TABLE
--添加主键
test=# alter table test1 add primary key(n_id);
ALTER TABLE test=# alter table test2 add primary key(n_id);
ALTER TABLE --插入数据耗时差别不大,test2表设置了fillfactor=70,占用空间更大。索引占用空间一样。
test=# insert into test1 select generate_series(1,1000000),'tttt'||generate_series(1,1000000);
INSERT 0 1000000
Time: 2500.057 ms (00:02.500)
test=# insert into test2 select generate_series(1,1000000),'tttt'||generate_series(1,1000000);
INSERT 0 1000000
Time: 2576.616 ms (00:02.577) test=# vacuum analyze test1;
VACUUM
test=# vacuum analyze test2;
--查看表的页数
test=# select relpages,reltuples from sys_class where relname = 'test1';
relpages | reltuples
----------+-----------
5435 | 1e+06
(1 row) test=# select relpages,reltuples from sys_class where relname = 'test2';
relpages | reltuples
----------+-----------
7752 | 1e+06
(1 row) --查看表结构
TEST=# \d+ test1
Table "public.test1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
n_id | integer | | not null | | plain | |
cc | character varying(300 char) | | | | extended | |
Indexes:
"test1_pkey" PRIMARY KEY, btree (n_id)
Access method: heap
Options: fillfactor=100 TEST=# \d+ test2
Table "public.test2"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
n_id | integer | | not null | | plain | |
cc | character varying(300 char) | | | | extended | |
Indexes:
"test2_pkey" PRIMARY KEY, btree (n_id)
Access method: heap
Options: fillfactor=70 --查看表大小,fillfactor设置越大占用的空间越小
TEST=# select sys_size_pretty(sys_relation_size('test1'));
sys_size_pretty
-----------------
42 MB
(1 row) Time: 0.642 ms
TEST=# select sys_size_pretty(sys_relation_size('test2'));
sys_size_pretty
-----------------
61 MB
(1 row) Time: 0.820 ms --查看主键大小
test=# select sys_size_pretty(sys_relation_size('test1_pkey'));
sys_size_pretty
----------------
22 MB
(1 row) test=# select sys_size_pretty(sys_relation_size('test2_pkey'));
sys_size_pretty
----------------
22 MB
(1 row) 更新数据时,R6版本,更新后,ctid没有明显区别,都是在第一页更新
R3版本更新后citd位置不同,
设置了fillfactor=100后,没有预留update空间,更新数据会在最后一页插入一条数据
而设置fillfactor=70,数据会在当前页插入一条数据 R6版本更新test1
test=# select ctid,* from test1 where n_id =1;
ctid | n_id | cc
-------+------+-----------
(0,1) | 1 | tttt1
(1 row) test=# update test1 set cc='ll' where n_id = 1;
UPDATE 1 更新test1, fillfactor为100,更新后,数据仍然插入到了第一页ctid为(0,185)
TEST=# select ctid,* from test1 where n_id =1;
ctid | n_id | cc
---------+------+----
(0,185) | 1 | ll
(1 row) 更新test2
test=# select ctid,* from test2 where n_id =1;
ctid | n_id | cc
-------+------+-----------
(0,1) | 1 | tttt1
(1 row) Time: 1.392 ms
test=# update test2 set cc='ll' where n_id = 1;;
UPDATE 1 test2表的fillfactor为70,还剩余20%的空间可以利用,更新后数据可以在第一页插入这条数据,ctid为 (0,130)
TEST=# select ctid,* from test2 where n_id =1;
ctid | n_id | cc
---------+------+----
(0,130) | 1 | ll
(1 row) 下面进行R3版本更新测试,重复以上步骤...
更新test1
TEST=# select ctid,* from test1 where n_id =1;
CTID | N_ID | CC
-------+------+-------
(0,1) | 1 | tttt1
(1 row) Time: 0.714 ms
TEST=# update test1 set cc='ll' where n_id = 1;
UPDATE 1
Time: 2.846 ms
TEST=# select ctid,* from test1 where n_id =1;
CTID | N_ID | CC
-----------+------+----
(5405,76) | 1 | ll
(1 row) 更新test2
test=# select ctid,* from test2 where n_id =1;
ctid | n_id | cc
-------+------+-----------
(0,1) | 1 | tttt1
(1 row) Time: 1.392 ms
test=# update test2 set cc='ll' where n_id = 1;;
UPDATE 1 R3版本更新test2表,fillfactor为70,更新后数据也可以在第一页插入这条数据
TEST=# select ctid,* from test2 where n_id =1;
ctid | n_id | cc
---------+------+----
(0,130) | 1 | ll
(1 row) 更新效率
--为了看出明显的效果,先将autovacuum关闭掉,更新test1的所有数据
在全量数据update的时候fillfactor=70的效率略高,少量数据update更新时候,低fillfactor表的效果更明显。
TEST=# update test1 set cc = cc||'xx';
UPDATE 1000000
Time: 4954.257 ms (00:04.954)
TEST=# update test2 set cc = cc||'xx';
UPDATE 1000000
Time: 3893.509 ms (00:03.894) TEST=# update test1 set cc = cc||'ee';
UPDATE 1000000
Time: 5649.721 ms (00:05.650)
TEST=# update test2 set cc = cc||'ee';
UPDATE 1000000
Time: 5041.635 ms (00:05.042) TEST=# update test1 set cc = cc||'tt';
UPDATE 1000000
Time: 5893.175 ms (00:05.893)
TEST=# update test2 set cc = cc||'tt';
UPDATE 1000000
Time: 5347.697 ms (00:05.348)
--经过三次全部更新来看,设置fillfactor=70时,更新的速度略快。 --更新小范围数据,test2表速度更快
TEST=# update test1 set cc = cc||'xxxx' where n_id>100 and n_id <200;
UPDATE 99
Time: 10.343 ms
TEST=# update test2 set cc = cc||'xxxx' where n_id>100 and n_id <200;
UPDATE 99
Time: 2.016 ms 更新后索引大小
可以看到设置了fillfactor=70表的索引比fillfactor=100的索引要小,而fillfactor=100膨胀的更快,这里 fillfactior和HOT技术结合起来看就不能理解,
当有空闲空间的时候,更新可能会用到HOT,数据是在一页内变动,所以索引会比默认fillfactor小。 --test1表的索引更大
TEST=# select sys_size_pretty(sys_relation_size('test1_pkey'));
sys_size_pretty
-----------------
86 MB
(1 row) Time: 4.932 ms
TEST=# select sys_size_pretty(sys_relation_size('test2_pkey'));
sys_size_pretty
-----------------
69 MB
(1 row) Time: 0.587 ms

总结

1.初始插入数据时,设置了不同fillfactor耗时差别不大,设置了fillfactor=70的表占用空间更大,新建的索引占用空间一样。

2.R3版本数据库中设置了fillfactor=100后,更新数据会在最后一页插入数据,而设置fillfactor=70,数据会在当前页空闲空间插入数据。

而R6版本数据库做了相关优化,fillfactor=100的表也可以插入数据到第一页。

3.在更新较频繁的表降低fillfactor可以提高更新效率,因为HOT技术,减小fillfactor的表,可以减小其索引膨胀。

4.在update(全量)的时候fillfactor=70的效率略高,少量数据更新的时候设置低的fillfactor效果更高。

KingbaseES V8R6 fillfactor 对于表的影响的更多相关文章

  1. KingbaseES V8R6备份恢复案例之---自定义表空间指定恢复目录数据恢复

    案例说明: KingbaseES V8R6在通过sys_rman执行物理备份恢复时,可以通过参数'--kb1-path',指定恢复的数据(data)目录,但如果原备份中包含自定义表空间时,需要建立表空 ...

  2. KingbaseES V8R6集群维护案例之---停用集群node_export进程

    案例说明: 在KingbaseES V8R6集群启动时,会启动node_exporter进程,此进程主要用于向kmonitor监控服务输出节点状态信息.在系统安全漏洞扫描中,提示出现以下安全漏洞: 对 ...

  3. KingbaseES V8R6兼容Oracle的exp-imp导出导入工具使用

    说明: KingbaseES V8R6版本中的兼容Oracle的exp-imp导入导出工具,支持完全模式.用户模式和表模式的导出功能. 本次案例数据库版本: test=# select version ...

  4. KingbaseES V8R6集群维护之--修改数据库服务端口案例

    ​ 案例说明: 对于KingbaseES数据库单实例环境,只需要修改kingbase.conf文件的'port'参数即可,但是对于KingbaseES V8R6集群中涉及到多个配置文件的修改,并且在应 ...

  5. KingbaseES V8R6集群维护案例之---将securecmdd通讯改为ssh案例

    案例说明: 在KingbaseES V8R6的后期版本中,为了解决有的主机之间不允许root用户ssh登录的问题,使用了securecmdd作为集群部署分发和通讯的服务,有生产环境通过漏洞扫描,在88 ...

  6. KingbaseES V8R6集群部署案例之---Windows环境配置主备流复制(异机复制)

    案例说明: 目前KingbaseES V8R6的Windows版本不支持数据库sys_rman的物理备份,可以考虑通过建立主备流复制实现数据库的异机物理备份.本案例详细介绍了,在Windows环境下建 ...

  7. KingbaseES V8R6集群部署案例之---Windows环境配置主备流复制(同一主机)

    案例说明: 目前KingbaseES V8R6的Windows版本不支持数据库sys_rman的物理备份,可以考虑通过建立主备流复制实现数据库的异机物理备份.本案例详细介绍了,在Windows环境下建 ...

  8. KingbaseES V8R6集群管理运维案例之---repmgr standby switchover故障

    案例说明: 在KingbaseES V8R6集群备库执行"repmgr standby switchover"时,切换失败,并且在执行过程中,伴随着"repmr stan ...

  9. KingbaseES V8R6备份恢复案例之---同一数据库创建不同stanza备份

    案例说明: 在生产环境,有的应用需要调用数据库的sys_rman做备份,为了区分数据库自身的sys_rman备份和应用的备份,可以使用不同的stanza name创建备份.本案例介绍了,如何在King ...

  10. kingbaseES V8R6集群备份恢复案例之---备库作为repo主机执行物理备份

    ​ 案例说明: 此案例是在KingbaseES V8R6集群环境下,当主库磁盘空间不足时,执行sys_rman备份,将集群的备库节点作为repo主机,执行备份,并将备份存储在备库的磁盘空间. 集群架构 ...

随机推荐

  1. Java设计模式-状态模式State

    介绍 状态模式(State Pattern):它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题.状态和行为是一一对应的,状态之间可以相互转换. 当一个对象的内在状态改变时,允许改变其行 ...

  2. win10安装和配置weblogic12c

    下载和安装 http://www.oracle.com/technetwork/middleware/ias/downloads/wls-main-097127.html ● 将jar放到jdk的bi ...

  3. 使用 Oracle PL/SQL NOCOPY 提示

    参考文献:       official document: http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/tuning.htm#LNPL ...

  4. 解决idea中使用git fetch报远程仓库Authentication failed

    这个问题是项目组同事在从git服务器clone代码后做fetch操作老是报错: Authentication failed, 弹出框提示:invalid user or password 其实问题出i ...

  5. macOS使用CodeRunner快速配置fortran环境

    个人网站:xzajyjs.cn 由于一些项目的缘故,需要有fortran的需求,但由于是M1 mac的缘故,不能像windows那样直接使用vs+ivf这种经典配置.搜了一下网上主流的跨平台方案,主要 ...

  6. .net+bootstrap写的一个还不错的音乐网站

    以前做的一款设计音乐网站,分享下. 技术用的是.net +sqlserver 大致的样子是这样的. 1.首页如下: 2.播放歌词页面如下:歌词自动滚动,且可悬停. 3.歌单信息页面如下: 详细页面如下 ...

  7. 【会员题】253. 会议室 II

    会议室II 给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间s1,e1,s2,e2]..](si<ei) ,为避免会议冲突,同时要考虑充分 利用会议室资源,请你计算至少需要多少间 ...

  8. 【LeetCode哈希表#4】梦开始的地方:两数之和(map),以及关于容器map的一些代码技巧

    两数之和 力扣题目链接(opens new window) 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种 ...

  9. Glide源码解析四(解码和转码)

    本文基于Glide 4.11.0 Glide加载过程有一个解码过程,比如将url加载为inputStream后,要将inputStream解码为Bitmap. 从Glide源码解析一我们大致知道了Gl ...

  10. Java 多态性的使用

    1 package com.bytezreo.duotai3; 2 3 /*** 4 * 5 * @Description 练习多态性的使用 6 * @author Bytezero·zhenglei ...