与Oracle相比,提高了postgreql插入性能。Postgresql线程的内存利用率低

与Oracle相比,提高了postgreql插入性能。Postgresql线程的内存利用率低,oracle,postgresql,insert,Oracle,Postgresql,Insert,我正在尝试改进Postgresql(9.2.3版)插入的性能,以使一个简单的表具有1个bigint、1个varchar、1个float和2个时间戳 附加了我的JDBC程序的简单复制。以下是我想提及的要点: 我在承载PostgreSQL数据库的同一个系统上运行这个程序。(64 GB RAM和8个CPU。) 我使用的是INSERT语句,不想使用COPY语句。我已经阅读并理解副本的性能更好,但我正在这里调整插入性能 我正在使用PreparedStatement.addbatch()和executeBa

我正在尝试改进Postgresql(9.2.3版)插入的性能,以使一个简单的表具有1个bigint、1个varchar、1个float和2个时间戳

附加了我的JDBC程序的简单复制。以下是我想提及的要点:

  • 我在承载PostgreSQL数据库的同一个系统上运行这个程序。(64 GB RAM和8个CPU。)
  • 我使用的是INSERT语句,不想使用COPY语句。我已经阅读并理解副本的性能更好,但我正在这里调整插入性能
  • 我正在使用PreparedStatement.addbatch()和executeBatch()批量插入1000个
  • 当我增加批处理大小时,insert的性能可以很好地扩展,但在大约8000个批处理大小时,insert的性能会趋于平稳。我注意到,系统上的postgresql线程是CPU饱和的,正如“top”命令所观察到的那样。postgres线程的CPU使用率稳步增加,当批处理大小达到8K时,CPU使用率达到95%。我注意到的另一件有趣的事情是,它每个线程仅使用高达200MB的RAM

    相比之下,Oracle DB的可扩展性要好得多,相同数量的具有可比批量大小的插入完成速度快3到4倍。我登录到Oracle DB机器(Sun Solaris机器)并注意到CPU利用率在更大的批处理大小时达到峰值,而且每个Oracle线程都在使用6到8 GB的内存

    既然我有多余的内存,有没有办法提高postgres线程的内存使用率以获得更好的性能

    以下是我当前的postgresql设置:

    temp_buffers = 256MB                    
    
    bgwriter_delay = 100ms
    bgwriter_lru_maxpages = 1000
    bgwriter_lru_multiplier = 4
    maintenance_work_mem = 2GB              
    shared_buffers = 8GB                    
    vacuum_cost_limit = 800
    work_mem = 2GB
    max_connections = 100
    
    checkpoint_completion_target = 0.9
    checkpoint_segments = 32
    checkpoint_timeout =10min
    checkpoint_warning =1min
    
    wal_buffers = 32MB
    wal_level = archive
    
    
    cpu_tuple_cost = 0.03
    effective_cache_size = 48GB
    random_page_cost = 2
    
    autovacuum = on
    autovacuum_vacuum_cost_delay = 10ms
    autovacuum_max_workers = 6
    autovacuum_naptime = 5
    autovacuum_vacuum_threshold = 100
    autovacuum_analyze_threshold = 100
    autovacuum_vacuum_scale_factor = 0.2
    autovacuum_analyze_scale_factor = 0.1
    autovacuum_vacuum_cost_limit = -1
    
    以下是测量结果:

    在postgreql中插入200万行的时间到了。 批次大小-执行批次时间(秒) 1K-73 2K-64 4K-60 8K-59 10K-59 20K-59 40K-59

    是时候在Oracle中插入400万行了。 批次大小-执行批次时间(秒) 1K-14 2K-12 4K-10 8K-8.9 10K-8.4

    正如您所见,Oracle插入400万行表的速度比Postgresql快得多

    下面是我用于插入的程序片段

    stmt.executeUpdate("CREATE TABLE "
                    + tableName
                    + " (P_PARTKEY bigint not null, "
                    + " P_NAME varchar(55) not null, "
                    + " P_RETAILPRICE float not null, "
                    + " P_TIMESTAMP Timestamp not null, "
                    + " P_TS2 Timestamp not null)");
    
    PreparedStatement pstmt = conn.prepareStatement("INSERT INTO " + tableName + " VALUES (?, ?, ?, ?, ? )");
    
            for (int i = start; i <= end; i++) {
                pstmt.setInt(1, i);
                pstmt.setString(2, "Magic Maker " + i);
                pstmt.setFloat(3, i);
                pstmt.setTimestamp(4, new Timestamp(1273017600000L));
                pstmt.setTimestamp(5, new Timestamp(1273017600000L));
    
                pstmt.addBatch();
                if (i % batchSize == 0) {
                    pstmt.executeBatch();
                }
            }
    
    stmt.executeUpdate(“创建表”
    +表名
    +(P_PARTKEY bigint not null)
    +P_NAME varchar(55)不为空
    +P_零售价格浮动不为空
    +P_时间戳时间戳不为空
    +“P_TS2时间戳不为空)”;
    PreparedStatement pstmt=conn.prepareStatement(“插入“+tableName+”值(?,,,,?,?)”;
    
    对于(int i=start;i Cross-post:只是一个小建议:您是否用另一种语言执行了相同的测试?Oracle和PostgreSQL之间的差异可能至少部分是由于所使用的JDBC驱动程序的差异。Cross-post:只是一个小建议:您是否用另一种语言执行了相同的测试?差异在于Oracle和PostgreSQL之间的区别可能至少部分是由于所使用的JDBC驱动程序的不同。