百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

PostgreSQL中数据批量导入优化方法

toyiye 2024-07-08 22:47 13 浏览 0 评论

现在很多企业都将数据库逐渐由Mysql转向了更加强大而且开源的PostgreSQL数据库。在数据迁移过程中,PostgreSQL数据库导入大量数据时候非常缓慢,本文我们就来说说PostgreSQL数据库批量导入数据时的优化方法和策略。

概述

考虑PostgreSQL数据库批量导入数据时性能缓慢的原因,无非有几个因素:索引,触发器,外键,GUID主键,还有可能是预写日志(WAL)。我们就从这几个影响因素着手优化。当然有可能,本文说的这些技巧都不能有效问题,遇到这样的问题时候,就需要我们具体问题具体分析,并针对性的解决。

关闭日志记录

对于PostgreSQL 9.5及更高版本,可以先将目标表更改为UNLOGGED,然后在加载数据后将其更改回LOGGED:

ALTER TABLE <target table> SET UNLOGGED
<批量导入数据…>
ALTER TABLE <target table> LOGGED

UNLOGGED模式可以确保PostgreSQL不会在变量导入数据时将表写操作记录到预写日志(WAL),从而极大的优化导入过程。但是,由于未记录操作,因此如果在加载过程中发生崩溃或服务器关机等故障,则无法恢复数据。PostgreSQL重新启动后将自动截断任何未记录的表。

另外,未记录的表不会复制到备用服务器。在这种情况下,必须在加载之前删除现有的复制,并在加载之后重新创建。根据主节点中的数据量和备用数据库的数量,重建复制的时间可能会很长,对于高可用性要求来说这是不可接受的。

建议采用以下方法,将数据批量插入未记录的表中:

在将表和数据更改为未记录模式之前对其进行备份;

数据加载完成后,重新创建对备用服务器的任何复制;

对可以轻松重新填充的表使用UNLOGGED的批量插入(例如,大型查找表或维度表)。

删除索引

数据库索引可能在批量数据插入期间导致严重的延迟。因为添加数据过程,对应的索引条目需要实时更新。

建议在开始批量插入之前尽可能删除目标表中的索引,并在导入完成后重新创建索引。同样,在大型表上创建索引可能很耗时,但是比在加载过程中更新索引要快。

DROP INDEX <index_name1>, <index_name2> … <index_name_n>
<批量导入数据…>
CREATE INDEX <index_name> ON <target_table>(column1, …,column n)

创建索引之前,临时提高maintenance_work_mem配置参数可能会有帮助。增加的工作内存可以帮助更快地创建索引。

为了安全起见的另一种选择是使用现有数据和索引在同一数据库中复制目标表。然后,测试有索引和删除索两种情况下批量导入数据的性能对比,然后根据测试结果选择更好的方法。

删除外键

和索引一样,外键约束也会影响大批量导入的性能。因为导入过程中必须检查插入的每个行数据的每个外键是否存在相应的主键。当批量导入时,必须为每一行触发该触发器检查外键,从而增加了开销。

除非受到业务规则的限制,否则建议先从目标表中删除所有外键,在单个事务中加载数据,然后在提交事务后重新创建外键。


ALTER TABLE <target_table>
DROP CONSTRAINT <foreign_key_constraint>

BEGIN TRANSACTION
<批量导入数据…>
COMMIT

ALTER TABLE <target_table>
ADD CONSTRAINT <foreign key constraint>
FOREIGN KEY (<foreign_key_field>)
REFERENCES <parent_table>(<primary key field>)...

同样增加maintenance_work_mem配置参数也能提高重新创建外键约束的性能。

暂停触发器

INSERT或DELETE触发器(如果导入过程还涉及从目标表中删除记录)可能会导致批量数据导入延迟。这是因为每个触发器将具有需要检查的逻辑,并且需要在每行被插入或删除后立即完成操作。

建议在批量导入数据之前禁用目标表中的所有触发器,并在导入完成后再启用它们。禁用所有触发器也会强制执行外键约束检查的系统触发器。

ALTER TABLE <target table> DISABLE TRIGGER ALL

<批量导入数据…>

ALTER TABLE <target table> ENABLE TRIGGER ALL

使用多值INSERT

对于成批数据加载,运行数千个或数十万个INSERT语句可能是个糟糕的选择。因为查询优化器必须解析和准备每个单独的INSERT命令,然后进行所有约束检查,作为单独的事务运行并记录日志。而使用多值单个INSERT语句可以节省这些不必要的开支。

INSERT INTO <target_table> (<column1>, <column2>, …, <column_n>)
VALUES
(<value a>, <value b>, …, <value x>),
(<value 1>, <value 2>, …, <value n>),
(<value A>, <value B>, …, <value Z>),
(<value i>, <value ii>, …, <value L>),
...


多值INSERT性能受现有索引的影响。建议在运行命令之前先删除索引,然后再创建索引。

另一个需要注意的地方是PostgreSQL可用于运行多值INSERT的内存量。运行多值INSERT时,RAM中必须容纳大量输入值,并且除非有足够的可用内存,否则该过程可能会失败。

建议将设置effective_cache_size参数到50%,并将shared_buffer设为机器的总内存的参数设为25%。为了安全起见,将导入划分为多条的多值INSERT,每个语句的值不要超过1000行。

使用COPY命令

建议使用PostgreSQL COPY命令从一个或多个文件导入数据。COPY针对批量数据导入会进行额外的优化,比运行大量INSERT语句甚至多值INSERTS的都要快。


COPY <target table> [( column1>, … , <column_n>)]
FROM '<文件路径>'
WITH (<option1>, <option2>, … , <option_n>)


使用COPY的还有很多的优势:

它支持文本和二进制文件导入;

本质上是事务性的;

它允许指定输入文件的结构;

它可以使用WHERE子句有条件地导入数据。

运行ANALYZ

这与提高批量数据导入性能无关,但是强烈建议在批量导入之后立即在目标表上运行ANALYZE命令。大量的新导入的行将大大改变数据表中列中的数据分布,并且会使表的统计信息都过时。当用查询优化器使用过时的统计信息时,查询性能可能会非常慢。运行ANALYZE命令将确保更新统计信息。

总结

对于数据库应用程序来说,可能并非每天都会进行批量数据导入,但是在运行时会对查询性能产生影响。这就是为什么有必要尽可能缩短导入时间。DBA可以最大程度地减少意外的事情之一就是在具有类似服务器规格和PostgreSQL配置的开发或准线上环境中进行性能测试并进行优化。每种数据加载方案都是不同的,最好尝试每种方法并找到最好最快的方法。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码