Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql内存表空间中的缓慢插入速度_Postgresql_Insertion - Fatal编程技术网

Postgresql内存表空间中的缓慢插入速度

Postgresql内存表空间中的缓慢插入速度,postgresql,insertion,Postgresql,Insertion,我需要以每秒10000条记录的速度将记录存储到数据库中(在几个字段上建立索引)。一条记录中的列数为25。我正在一个事务块中批量插入100000条记录。为了提高插入率,我将表空间从磁盘改为RAM,这样我每秒只能插入5000次 我还在postgres配置中进行了以下调整: 索引:否 fsync:false 日志记录:禁用 其他资料: 表空间:RAM 一行中的列数:25(多数为整数) CPU:4核,2.5 GHz 内存:48 GB 我想知道为什么当数据库不在磁盘上写入任何内容时(因为我使用的是

我需要以每秒10000条记录的速度将记录存储到数据库中(在几个字段上建立索引)。一条记录中的列数为25。我正在一个事务块中批量插入100000条记录。为了提高插入率,我将表空间从磁盘改为RAM,这样我每秒只能插入5000次

我还在postgres配置中进行了以下调整:

  • 索引:否
  • fsync:false
  • 日志记录:禁用
其他资料:

  • 表空间:RAM
  • 一行中的列数:25(多数为整数)
  • CPU:4核,2.5 GHz
  • 内存:48 GB
我想知道为什么当数据库不在磁盘上写入任何内容时(因为我使用的是基于RAM的表空间),单个插入查询平均需要0.2毫秒左右的时间。我做错什么了吗

谢谢你的帮助


Prashant

您是否将插入作为一系列

INSERT INTO tablename (...) VALUES (...);
INSERT INTO tablename (...) VALUES (...);
...
或作为一个多行插入:

INSERT INTO tablename (...) VALUES (...),(...),(...);
第二个将在10万行上显著更快


来源:

您是否也在RAM驱动器上放置了xlog(WAL段)?如果没有,您仍在向磁盘写入数据。那么wal_缓冲区、检查点_段等的设置呢?您必须尝试在wal_缓冲区中获取所有100000条记录(单笔交易)。增加此参数可能会导致PostgreSQL请求的System V共享内存超过操作系统默认配置允许的数量

我建议您使用
复制
而不是
插入

您还应该微调postgresql.conf文件

阅读有关快速数据加载的信息
  • 将数据转换为CSV
  • 创建一个临时表(如您所述,没有索引)
  • 执行复制命令:
    \COPY schema.temp_table FROM/tmp/data.csv WITH csv
  • 将数据插入非临时表
  • 创建索引
  • 设置适当的统计数据
  • 进一步建议 对于大量数据:

  • 将数据拆分为子表
  • 按大多数
    SELECT
    语句将使用的列的顺序插入。换句话说,尝试将物理模型与逻辑模型对齐
  • 调整您的配置设置
  • 创建一个
    集群
    索引(最重要的列位于左侧)。例如:
  • PostgreSQL配置
  • 编辑
    /etc/postgresql/8.4/main/postgresql.conf
    并设置: shared_buffers = 1GB temp_buffers = 32MB work_mem = 32MB maintenance_work_mem = 64MB seq_page_cost = 1.0 random_page_cost = 2.0 cpu_index_tuple_cost = 0.001 effective_cache_size = 512MB checkpoint_segments = 10 子表 表统计 增加重要列的表统计信息:

    ALTER TABLE climate.measurement_001 ALTER COLUMN taken SET STATISTICS 1000;
    ALTER TABLE climate.measurement_001 ALTER COLUMN station_id SET STATISTICS 1000;
    

    不要忘了用真空吸尘器和事后分析。

    我使用的是第一种方法:-开始;-插入到tablename(…)值(…);-插入到tablename(…)值(…);-…-犯罪我现在尝试第二种方法。感谢这篇文章还建议拷贝速度更快,因为xlog安装在RAM驱动器上。一行的大小约为240字节。因此,对于一批100000条记录,我将wal_缓冲区大小设置为250MB。通过这些设置,我每秒可以获得大约6000-7000次插入。是否有任何方法来分析博士后,看看哪个操作需要时间。由于磁盘上没有写入数据,内存传输应该相对非常快。每秒6000次插入~=1.5 MB/s,我认为这非常慢。 shared_buffers = 1GB temp_buffers = 32MB work_mem = 32MB maintenance_work_mem = 64MB seq_page_cost = 1.0 random_page_cost = 2.0 cpu_index_tuple_cost = 0.001 effective_cache_size = 512MB checkpoint_segments = 10
    CREATE TABLE climate.measurement
    (
      id bigserial NOT NULL,
      taken date NOT NULL,
      station_id integer NOT NULL,
      amount numeric(8,2) NOT NULL,
      flag character varying(1) NOT NULL,
      category_id smallint NOT NULL,
      CONSTRAINT measurement_pkey PRIMARY KEY (id)
    )
    WITH (
      OIDS=FALSE
    );
    
    CREATE TABLE climate.measurement_001
    (
    -- Inherited from table climate.measurement_001:  id bigint NOT NULL DEFAULT nextval('climate.measurement_id_seq'::regclass),
    -- Inherited from table climate.measurement_001:  taken date NOT NULL,
    -- Inherited from table climate.measurement_001:  station_id integer NOT NULL,
    -- Inherited from table climate.measurement_001:  amount numeric(8,2) NOT NULL,
    -- Inherited from table climate.measurement_001:  flag character varying(1) NOT NULL,
    -- Inherited from table climate.measurement_001:  category_id smallint NOT NULL,
      CONSTRAINT measurement_001_pkey PRIMARY KEY (id),
      CONSTRAINT measurement_001_category_id_ck CHECK (category_id = 1)
    )
    INHERITS (climate.measurement)
    WITH (
      OIDS=FALSE
    );
    
    ALTER TABLE climate.measurement_001 ALTER COLUMN taken SET STATISTICS 1000;
    ALTER TABLE climate.measurement_001 ALTER COLUMN station_id SET STATISTICS 1000;