pg_bulkload数据加载工具

pg_bulkload,数据批量加载的工具。在PostgreSQL内部,也有数据加载的工具,比如copy。本文会对比pg_bulkload与copy之间的差异。
在介绍pg_bulkload这类数据加载工具之前,先分析一下这类工具存在的原因。我们都知道往数据库里插入数据是用insert into table_name values (...),如果一次插入的数据量很大这种方式性能就很差。我们首先分析PostgreSQL内部insert的执行过程,从中窥探出影响性能的原因。
1、insert
在pg内部,一条Insert语句的一般执行步骤如下:
1、开启事务
2、词法语法解析
3、语法树重写
4、执行器执行,这里面包括完整性检查、插入元组、写日志、建索引
5、关闭日志。
在pg内部,insert默认是autocommit,就是说一条insert就会开启一个事务,批量插入数据时这种开销是很影响性能的。insert执行过程中主要调用函数如下:


pg_bulkload数据加载工具_第1张图片
图1 insert函数执行流程

insert过程与插入元组直接相关的就是heap_insert函数,heap_insert函数内部会把用户传入的元组的值写入共享内存,同时heap_insert内部还会调用XLogInsert函数写日志。那我们就分析一下影响插入性能的因素有哪些,我们主要关注的是一次插入的数据量非常大时的影响因素,当插入数据量很少时,某些影响因素可能并不明显。从图1可以看出与insert本身直接相关的就是heap_insert函数了,如果是批量加载数据的话,那么可以设想其他的步骤能不能省略呢?比如说只开启一个事务,不需要查询解析更甚者是不写日志。这些因素都可以提高insert的性能,但是也是有代价的。
2、 pg_bulkload
pg_bulkload是数据加载工具,速度快,可以从文件导入数据,介绍一下它的使用。
pg_bulkload安装需要pg_config,所以需要把pg的bin目录导入PATH,
eport PATH=/Users/wanggang/pg9.4/bin:$PATH
进入pg_bulkload目录,
make USE_PGXS=1
make USE_PGXS=1 install
这样pg_bulkload就安装完了
进入数据库创建extension, create extension pg_bulkload
进入pg_bulkload的bin目录,在这个目录下有两个命令,一个是postgresql,启动、关闭数据库,是对pg_ctl的封装,另一个是pg_bulkload,数据加载的命令。可先利用copy命令创建一个csv格式的文件,然后用这个文件去填充表。
安装

pg_bulkload数据加载工具_第2张图片
图2 pg_bulkload安装
pg_bulkload数据加载工具_第3张图片
图3 创建extension

现在把我本地磁盘上test.sql文件中的数据导入数据库test表里,数据量3.6G,同时也会用copy导入,测试两者的性能差异。

pg_bulkload数据加载工具_第4张图片
图4 插入结果

-i 输入磁盘文件,一般是csv格式的文件
-O 输出文件或者是表,图4中是数据库中的表
-l 日志文件,执行过程中的信息保存在日志文件中
-h 主机地址,图4中用PGHOST环境变量表示,libpq也需要此参数
-p 端口号,默认5432
-d 数据库,图4中是我建的test的数据库

pg_bulkload数据加载工具_第5张图片
图5 输出日志结果

从图5中可以得出本次导入的时间开销是95.5秒,执行方式是DIRECT,还有PARALLEL的处理方式,默认是DIRECT模式。利用COPY测试它的性能如何。

pg_bulkload数据加载工具_第6张图片
图6 copy的测试结果

图6显示copy的测试结果是172秒,pg_bulkload的性能优势还是很明显的。copy与pg_bulkload的工作原理还是很相似的,主要三个步骤:1、逐行解析文件,2、构造元组,3、将构造出的元组插入表。两者实现上的区别在第三步,copy将构造出的元组插入共享内存,同时写日志,pg_bulkload绕过了共享内存,不写日志,这样会减少磁盘I/O,但是也很危险。

你可能感兴趣的:(pg_bulkload数据加载工具)