PostgreSQL笔记25:数据写入与读取流程及IO模型演进

通过copyIn向PostgreSQL或Greenplum写入数据 最近需要向PG写入百万级的数据,分别尝试了Spark、jdbc写法,发现性能都不是特别好,差不多都得花上几分钟,有可能是PG本身没有进行优化,或者编程过程中有欠缺的地方。总之,达不到业务需求。后面改用PG的copyIn方法,发现写入百万数据只需要秒级别。下面将demo代码附上,与君共享,有不足的地方,万望指正。 pom依赖: <dependency> <g... 阅读详情

纲要

  • PostgreSQL 体系架构概览
    • 进程模型与内存结构
    • 共享内存(shared_buffers、wal_buffers)
    • 后台进程(BGWriter、WALWriter、Checkpointer)
  • 数据读写流程
    • 读取路径:shared_buffers → OS Page Cache → 磁盘
    • 写入路径:脏页刷盘与 WAL 持久化
  • 双缓存问题(核心难点)
    • 数据重复缓存,内存浪费
    • 操作系统 LRU 与数据库 Clock Sweep 算法不匹配
  • 页面置换算法:Clock Sweep(时钟扫描)
    • usage_count 机制与指针旋转
  • IO 模型演进
    • 传统 Buffered IO
    • Direct IO 引入计划(PG 16 → 18 → 19/20)
    • AIO(异步 IO)基础设施
  • PostgreSQL 的独特视角:无逻辑读/物理读之分

体系架构概览

PostgreSQL 采用多进程架构,每个客户端连接对应一个独立的 backend process。内存分为:

  • 共享内存:包括 shared_buffers(数据页缓存)、wal_buffers(日志缓冲)、锁结构、ProcArray 等。
  • 私有内存:每个后端进程的 work_mem、maintenance_work_mem 等。

数据文件存储在 $PGDATA/base 目录下,每个表对应一个或多个文件(relfilenode),文件内部由 8KB 的页(page/block)组成。

客户端

后端进程

共享内存

shared_buffers

wal_buffers

锁

本地内存

work_mem

操作系统 Page Cache

磁盘数据文件

WAL 文件

后台进程

BGWriter

WALWriter

Checkpointer

后台进程负责将脏页刷入磁盘(BGWriter)和 WAL 日志持久化(WALWriter),Checkpointer 定期执行检查点,保证崩溃恢复点。

数据读写流程

读取路径

  1. 后端进程发起数据页请求。
  2. 在 shared_buffers 的哈希表中查找,若命中则直接返回。
  3. 若未命中,调用 read() 系统调用,操作系统先查看自身 Page Cache,若命中则返回,否则触发磁盘 IO。
  4. 数据先被加载到 Page Cache,再拷贝到 shared_buffers 中的空闲槽位。若 shared_buffers 已满,则通过 Clock Sweep 淘汰一个页。

写入路径

  • 数据修改在 shared_buffers 中标记为脏页。
  • 脏页不会立即落盘,而是由 BGWriter 定期批量写入,或由 Checkpointer 在检查点期间强制写入。
  • WAL 日志通过 WALWriter 持久化,保证事务提交后即使宕机也能恢复。
  • 写入时同样经过操作系统 Page Cache,最终由操作系统调度刷盘(除非使用 O_DIRECT 或 fsync)。
BGWriter Disk OS Page Cache shared_buffers Backend Client BGWriter Disk OS Page Cache shared_buffers Backend Client alt [命中] [未命中] loop [后台刷新] SQL 查询 查页 直接返回 read() 物理读 数据 填充 返回 修改页(标记脏) 扫描脏页 write() 异步写入

双缓存问题

PostgreSQL 同时维护 shared_buffers 和操作系统 Page Cache,导致同一数据页可能被缓存两次,造成内存浪费。更严重的是,操作系统的 LRU 淘汰算法不了解数据库的访问模式,可能将数据库即将访问的热数据淘汰,而数据库自己的 Clock Sweep 算法才能根据 usage_count 和 pin 状态做出更准确的决策。

具体表现:

  • 内存利用率低,尤其在 shared_buffers 较大时,双缓存加重内存压力。
  • IO 路径冗长:数据需从磁盘→OS缓存→shared_buffers,经历两次内存拷贝。
  • 刷脏时,操作系统可能过度刷盘,引发性能抖动。

社区早已认识到此问题,并计划引入 Direct IO 来绕过操作系统缓存,让数据库完全自主管理 IO。

页面置换算法:Clock Sweep

shared_buffers 采用 Clock Sweep(时钟扫描)算法,代替传统 LRU。每个缓存页有一个 usage_count 计数器:

  • 每次访问该页,usage_count 加 1(上限可调)。
  • 一个后台扫描进程(或分配新页时的扫描)循环遍历所有页,每扫描一次将 usage_count 减 1。
  • 当 usage_count 减至 0 时,该页被选中淘汰。
  • 如果页被 pin 住(正在被访问),则跳过淘汰。

这种机制类似于钟表指针旋转,因此得名。它避免维护链表,且能较好地反映近期访问频率。

>0

=0

指针循环

usage_count?

减1, 继续前进

淘汰, 载入新页

IO 模型演进

当前:Buffered IO(默认)

所有数据读写均经过操作系统 Page Cache。参数 wal_sync_method 可控制 WAL 是否使用 O_DIRECT,但数据文件读写始终走缓存。

演进路线

  • PostgreSQL 16:引入实验性参数 debug_io_direct,允许开发者在某些场景测试 Direct IO,不可用于生产。
  • PostgreSQL 17:引入 read_stream 框架,为异步 IO 准备接口。
  • PostgreSQL 18:正式引入 AIO(异步 IO)基础设施,支持 io_uring(Linux)和 worker(其他平台)两种模式,可提升顺序扫描、VACUUM 等操作的性能。
  • PostgreSQL 19/20(预期):实现完整的 Direct IO,彻底避免双缓存,数据直接通过 DMA 在磁盘和 shared_buffers 间传输,减少 CPU 拷贝,并允许数据库根据自身访问模式精细管理内存。

Direct IO 的优势

  • 消除双缓存,释放内存。
  • 减少内核态/用户态数据拷贝,降低 CPU 开销。
  • 避免操作系统盲目刷脏,减少 IO 抖动。
  • 数据库可根据 usage_count 和 pin 信息智能淘汰,命中率更高。

注意事项

即使使用 Direct IO,仍然需要 fsync 或 O_DSYNC 保证持久性。目前 AIO 主要支持读操作,写操作仍为同步,后续版本会逐步增强。

API 速览

本部分列举涉及的核心 PostgreSQL 系统视图和扩展函数。

1. pg_stat_bgwriter

  • 所属:系统视图(无需扩展)
  • 功能:统计后台写入进程的活动信息。
  • 关键字段:
    • checkpoints_timed:定期检查点次数
    • checkpoints_req:请求检查点次数
    • buffers_checkpoint:检查点期间写入的缓冲数
    • buffers_clean:BGWriter 主动清理的脏页数
    • maxwritten_clean:因写入过多而停止的次数
  • 示例:
SELECT checkpoints_timed, checkpoints_req, buffers_checkpoint, buffers_clean
FROM pg_stat_bgwriter;

2. pg_buffercache 扩展

  • 所属:需 CREATE EXTENSION pg_buffercache;
  • 功能:查看 shared_buffers 中每个缓存页的详细信息。
  • 关键字段:
    • bufferid:缓冲槽编号
    • relfilenode:表文件节点
    • reltablespace:表空间 OID
    • relblocknumber:页号
    • isdirty:是否为脏页
    • usagecount:当前访问计数
  • 示例:
SELECT COUNT(*) AS total_buffers,
       SUM(CASE WHEN isdirty THEN 1 ELSE 0 END) AS dirty_buffers,
       AVG(usagecount) AS avg_usage
FROM pg_buffercache;

3. pg_stat_reset() 函数

重置所有统计计数器,用于性能测试。

SELECT pg_stat_reset();

Demo 简单示例(Node.js 完整)

以下示例使用 Node.js 的 pg 库连接 PostgreSQL,创建测试表,执行多次随机查询,并查看 shared_buffers 状态和 bgwriter 统计。

运行说明

  1. 安装依赖:npm install pg
  2. 确保 PostgreSQL 运行,数据库 postgres 可用。
  3. 执行命令:node demo.js

代码说明

  • 创建表 test_cache 并插入 1000 条数据。
  • 执行 5 次随机单点查询,记录耗时。
  • 查询 pg_stat_bgwriter 和 pg_buffercache(需提前建扩展)获取缓存统计。

技术点总结

  • 数据库连接、参数化查询。
  • 系统视图使用。
  • 性能监控基础。
// demo.js
import { Client } from 'pg';

const client = new Client({
  user: 'postgres',
  password: 'postgres',
  host: 'localhost',
  database: 'postgres',
  port: 5432,
});

async function run() {
  await client.connect();

  // 创建测试表
  await client.query(`
    CREATE TABLE IF NOT EXISTS test_cache (
      id SERIAL PRIMARY KEY,
      data TEXT
    );
  `);

  // 插入 1000 条数据
  await client.query(`
    INSERT INTO test_cache (data)
    SELECT generate_series(1,1000)::text;
  `);

  // 执行 5 次随机查询
  for (let i = 0; i < 5; i++) {
    const id = Math.floor(Math.random() * 1000) + 1;
    const start = Date.now();
    const res = await client.query('SELECT * FROM test_cache WHERE id = $1', [id]);
    console.log(`Query ${i+1} took ${Date.now() - start}ms, rows: ${res.rowCount}`);
  }

  // 查看 bgwriter 统计
  const bg = await client.query('SELECT * FROM pg_stat_bgwriter');
  console.log('BGWriter stats:', bg.rows[0]);

  // 启用缓冲页查看扩展
  await client.query('CREATE EXTENSION IF NOT EXISTS pg_buffercache');
  const cache = await client.query(`
    SELECT COUNT(*) AS total_buffers,
           SUM(CASE WHEN isdirty THEN 1 ELSE 0 END) AS dirty_buffers,
           ROUND(AVG(usagecount), 2) AS avg_usage
    FROM pg_buffercache;
  `);
  console.log('Buffer cache status:', cache.rows[0]);

  await client.end();
}

run().catch(console.error);

对应的原生 PostgreSQL 指令(注释):

-- 创建表
CREATE TABLE test_cache (id SERIAL PRIMARY KEY, data TEXT);
-- 插入数据
INSERT INTO test_cache (data) SELECT generate_series(1,1000)::text;
-- 随机查询(示例)
SELECT * FROM test_cache WHERE id = 1;
-- 查看 bgwriter
SELECT * FROM pg_stat_bgwriter;
-- 查看缓冲池(需扩展)
CREATE EXTENSION IF NOT EXISTS pg_buffercache;
SELECT COUNT(*) AS total_buffers, SUM(CASE WHEN isdirty THEN 1 ELSE 0 END) AS dirty_buffers, ROUND(AVG(usagecount), 2) AS avg_usage FROM pg_buffercache;

多语言示例

以下分别使用 Go、Python、Java 实现相同逻辑。

Go

package main

import (
    "database/sql"
    "fmt"
    "math/rand"
    "time"
    _ "github.com/lib/pq"
)

func main() {
    connStr := "user=postgres password=postgres dbname=postgres host=localhost port=5432 sslmode=disable"
    db, err := sql.Open("postgres", connStr)
    if err != nil {
        panic(err)
    }
    defer db.Close()

    // 创建表
    _, err = db.Exec(`CREATE TABLE IF NOT EXISTS test_cache (id SERIAL PRIMARY KEY, data TEXT)`)
    if err != nil {
        panic(err)
    }
    // 插入数据
    _, err = db.Exec(`INSERT INTO test_cache (data) SELECT generate_series(1,1000)::text`)
    if err != nil {
        panic(err)
    }

    rand.Seed(time.Now().UnixNano())
    for i := 0; i < 5; i++ {
        id := rand.Intn(1000) + 1
        var data string
        start := time.Now()
        err = db.QueryRow(`SELECT data FROM test_cache WHERE id = $1`, id).Scan(&data)
        if err != nil {
            panic(err)
        }
        fmt.Printf("Query %d took %v\n", i+1, time.Since(start))
    }

    // bgwriter stats
    var checkpointsTimed, buffersCheckpoint, buffersClean int
    err = db.QueryRow(`SELECT checkpoints_timed, buffers_checkpoint, buffers_clean FROM pg_stat_bgwriter`).Scan(&checkpointsTimed, &buffersCheckpoint, &buffersClean)
    if err != nil {
        panic(err)
    }
    fmt.Printf("BGWriter: checkpoints_timed=%d, buffers_checkpoint=%d, buffers_clean=%d\n", checkpointsTimed, buffersCheckpoint, buffersClean)
}

Python

import psycopg2
import random
import time

conn = psycopg2.connect(
    host="localhost",
    database="postgres",
    user="postgres",
    password="postgres"
)
cur = conn.cursor()

cur.execute("CREATE TABLE IF NOT EXISTS test_cache (id SERIAL PRIMARY KEY, data TEXT)")
cur.execute("INSERT INTO test_cache (data) SELECT generate_series(1,1000)::text")
conn.commit()

for i in range(5):
    id = random.randint(1, 1000)
    start = time.time()
    cur.execute("SELECT data FROM test_cache WHERE id = %s", (id,))
    row = cur.fetchone()
    print(f"Query {i+1} took {(time.time()-start)*1000:.2f}ms")

cur.execute("SELECT checkpoints_timed, buffers_checkpoint, buffers_clean FROM pg_stat_bgwriter")
row = cur.fetchone()
print(f"BGWriter: checkpoints_timed={row[0]}, buffers_checkpoint={row[1]}, buffers_clean={row[2]}")

cur.close()
conn.close()

Java

import java.sql.*;
import java.util.Properties;
import java.util.Random;

public class PgDemo {
    public static void main(String[] args) throws Exception {
        String url = "jdbc:postgresql://localhost:5432/postgres";
        Properties props = new Properties();
        props.setProperty("user", "postgres");
        props.setProperty("password", "postgres");
        Connection conn = DriverManager.getConnection(url, props);

        Statement stmt = conn.createStatement();
        stmt.execute("CREATE TABLE IF NOT EXISTS test_cache (id SERIAL PRIMARY KEY, data TEXT)");
        stmt.execute("INSERT INTO test_cache (data) SELECT generate_series(1,1000)::text");

        Random rand = new Random();
        for (int i = 0; i < 5; i++) {
            int id = rand.nextInt(1000) + 1;
            long start = System.currentTimeMillis();
            ResultSet rs = stmt.executeQuery("SELECT data FROM test_cache WHERE id = " + id);
            rs.next();
            System.out.println("Query " + (i+1) + " took " + (System.currentTimeMillis() - start) + "ms");
        }

        ResultSet bg = stmt.executeQuery("SELECT checkpoints_timed, buffers_checkpoint, buffers_clean FROM pg_stat_bgwriter");
        bg.next();
        System.out.println("BGWriter: checkpoints_timed=" + bg.getInt(1) + ", buffers_checkpoint=" + bg.getInt(2) + ", buffers_clean=" + bg.getInt(3));

        stmt.close();
        conn.close();
    }
}

多语言对比

语言驱动/库连接方式参数化查询结果处理适用场景
Node.jspgClient 对象,连接字符串或配置对象$1, $2 占位符异步 Promise / 回调高并发 I/O 密集型
Gogithub.com/lib/pqsql.Open("postgres", connStr)$1, $2 占位符同步,Scan 到变量高性能服务端
Pythonpsycopg2connect() 关键字参数%s 占位符游标迭代或 fetchone数据分析、脚本
Javaorg.postgresql.DriverDriverManager.getConnection(url, props)字符串拼接(避免,建议 PreparedStatement)ResultSet 遍历企业级应用

项目难点与解决方案

核心难点

  • 双缓存导致内存浪费和性能波动。
  • 操作系统缓存与数据库缓存策略不协调,造成不必要的 IO。
  • 现有 Buffered IO 路径长,CPU 拷贝开销大。

解决方案

  • 社区推动 Direct IO 和 AIO,逐步消除双缓存。
  • 通过监控 pg_stat_bgwriter 和 pg_buffercache,调整 shared_buffers、bgwriter_delay 等参数缓解问题。
  • 对于高频访问场景,可考虑使用较大的 shared_buffers 并减少操作系统缓存(vm.dirty_ratio 调优)。

广度

涉及数据库内核、操作系统存储栈、硬件 DMA、异步编程等。

深度

深入分析了 Clock Sweep 算法、缓存一致性、IO 路径层次。

复杂度

需要理解内核态/用户态切换、DMA、异步 IO 模型,以及 PostgreSQL 多进程并发控制。

官方文档

参考链接

总结

本文系统讲解了 PostgreSQL 的数据读写流程,重点剖析了双缓存问题的成因与影响,并介绍了 Clock Sweep 页面置换算法。随着社区推进 Direct IO 和 AIO,未来 PostgreSQL 将实现更高效的内存管理和 IO 性能,彻底告别双缓存弊端。

当前生产环境可通过监控 pg_stat_bgwriter 和 pg_buffercache 进行针对性调优,并关注新版本 IO 特性。多语言示例展示了跨语言连接 PostgreSQL 的标准实践,方便开发者快速集成。

PostgreSQL内核解析与国产数据库演进:从架构到选型实践 数据库作为现代应用的核心基础设施,其架构设计与技术选型直接影响系统的稳定性与扩展性。多版本并发控制(MVCC)是保障高并发读写一致性的关键机制,通过维护数据行的多个版本实现读写隔离,避免了传统锁机制的性能瓶颈。这一原理在高并发场景下尤为重要,能够显著提升系统的吞吐能力。随着数据规模的扩大和业务场景的复杂化,数据库的可扩展性成为技术选型的重要考量。PostgreSQL以其开放的内核架构和强大的扩展能力,支持自定义数据类型、索引方法和外部数据集成,为二次开发提供了坚实基础。在国产化替代和云原生转型的背景下,基于 阅读详情

相关推荐

PostgreSQL:详解 PostgreSQL 与Hadoop与Spark的集成

本文介绍了PostgreSQL与Hadoop生态及Spark的深度集成方案。PostgreSQL作为OLTP数据库,通过与Hadoop(HDFS/Hive)和Spark的协同,可构建完整的混合数据处理平台。核心集成方式包括:1)使用Sqoop或Debezium实现PG与Hadoop间的批量和实时数据同步;2)通过Spark JDBC实现PG与Spark的双向数据交互;3)借助联邦查询引擎(如Trino)统一访问PG和Hive数据。文章详细阐述了各集成方案的配置方法、性能优化技巧及适用场景,为构建HTAP平台

数据知道的博客 2387

python读取和写入PostgreSQL问题总结

Python读取PostgreSQL数据 流程如下: import psycopg2 #连接数据库 conn = psycopg2.connect(database = 'name', user = 'admin', password = '123456', host = '10.10.10.10', port = '5432') curs=conn.cursor() #编写Sql,只...

书生的日常 1万+

如何使用 httpx + SQLAlchemy 异步高效写入上亿级图片链接与MD5到 PostgreSQL

本文介绍了基于Python异步生态的高性能批量数据写入方案,针对亿级数据场景提出优化策略。核心采用httpx+SQLAlchemy 2.0+asyncpg技术组合,实现40,000+条/秒的稳定写入吞吐。文章详细分析了技术选型原因,比较了不同方案的性能差异,推荐使用原生SQL+ON CONFLICT DO NOTHING的批量写入方式。在数据库设计方面,提出使用CHAR(32)作为主键、TEXT存储URL的紧凑表结构,并给出分区表方案。最后提供了完整的代码实现,包括异步连接池配置、批量插入逻辑等关键细节,形

数据知道的博客 3491

Postgresql快速写入\/读取大量数据(.net)

环境及测试 使用.net驱动npgsql连接post数据库。配置:win10 x64, i5-4590, 16G DDR3, SSD 850EVO. postgresql 9.6.3,数据库与数据都安装在SSD上,默认配置,无扩展。 CREATE TABLE public.mesh (  x integer NOT NULL,  y integer NOT NULL,  z integ

dotNET跨平台 1523

华北理工大学以升实验班蓝桥杯选拔赛题解

文章目录华北理工大学以升实验班蓝桥杯选拔赛题解A:期末考试题目描述题目讲解代码B:月份题目描述题目讲解代码C:打饭题目描述题目讲解代码D : 正弦波信号题目描述题目讲解代码E : 亲爱的长方形题目描述题目讲解代码F:挖金子题目描述题目讲解代码G : 金金的游戏题目描述题目讲解代码H : 区间和题目描述题目讲解代码详细视频讲解请关注华北理工大学b站账号。 华北理工大学以升实验班蓝桥杯选拔赛题解 A:期末考试 题目描述 Description 期末考试过去许多天了,如今成绩都出来了,那么现在让我们对成绩我分个类

Qq1739206233的博客 1130

App渗透 - 人脸识别登录绕过

一、APP抓包和逆向破解加密算法打开APP是一个登录框抓包后发现参数被加密了使用Jadx脱源码发现,并没有加壳也没有混淆,运气很好根据经验,先搜索Encrypt、Decrypt等关键字,发现在Common.js中有一个encryptData函数定位过去,一套加解密算法都写好了放在这放到浏览器console里面调试,果然没错二、寻找注入点首先测试了一下注入明文:{"userName":"TEST'...

渗透测试研究中心 2827

postgresql mysql速度_MySql,PostgreSql,SqlServer数据写入读取速度对比测试

一、配置信息1.硬件配置Cpu:i5-5200U内存:8G2.软件配置Myeclipse 10Jdk:1.8二、数据库信息1.数据库版本数据库MySqlPostgreSQLMicrosoft SQL Server版本号5.0.189.5.610.00.16002.数据库设计表名Sql_compareidvatcharxintyintzint三、插入数...

weixin_33999969的博客 1227

Docker篇——Docker常用命令大全!史上最全面的Docker命令,涵盖常规命令、镜像基本命令、容器基本命令以及常用其他命令,一篇文章速通!

本篇文章介绍的关于DOcker的命令非常全面,Docker常见的命令介绍完毕,涉及到的命令比较繁杂,希望大家可以收藏并坚持学习。后续还会持续更新相关技术点,敬请期待

我热爱学习,也乐于分享。无论是科技前沿的洞见,还是生活中的小技巧,我都会在这里与你分享。我相信,知识就是力量,而分享则能让这份力量得到更好的传递。 5748

Python办公自动化之PostgreSQL篇3——利用Python读取一张表写入PostgreSQL

Python办公自动化之PostgreSQL篇3——利用Python读取一张表写入PostgreSQL python写入Excel

weixin_42636075的博客 1823

内容分析指南(The Content Analysis Guidebook Second Edition)

The Content Analysis Guidebook Second Edition Kimberly A. Neuendorf Cleveland State University 下载地址: 用于分析交互媒体(社交媒体等)中的内容 目录 Contents List of Boxes List of Tables and Figures Preface Acknowled...

NULL 2168

42、InfiniBand技术详解:QP状态机、操作及错误处理

本文深入解析InfiniBand技术中的核心组件QP(Queue Pair)状态机、工作请求处理机制、支持的操作类型及错误处理策略。详细介绍了QP的创建与状态转换流程,包括INIT、RTR、RTS等关键状态,并提供了状态修改的代码示例。文章还探讨了工作请求的发布、资源使用限制、围栏机制以及重试和RNR流程,帮助开发者理解通信可靠性保障机制。此外,涵盖了多播组的应用场景与API使用方法,并对比了用户空间与内核级RDMA API的调用差异,最后给出了实践建议和常见问题解答,为构建高性能分布式系统提供技术指导。

oauth7security的博客 133

Postgresql快速写入/读取大量数据(.Net)

postgresql使用copy导入的时候,如果目标表已经有数据,那么在有主键约束的表遇到错误时,COPY自动终止,而且可能导致不完全插入的情况,换言之,是不支持导入的过程进行update操作;还在前面的基础上,使用多线程,每个线程建立一个连接,一个连接处理100条sql语句,每条sql语句插入1000条数据,以此种方式进行导入。CPU占用率不到25%,磁盘写入63MB/S左右,但是,使用单行插入的方式,效率没有改观,时间太长还是等不来结果。没有最好的,只有最合适的,讲道理我也是挺喜欢用mysql的。

wuyy0224的博客 2981

ESP32-CAM 赋能 AI 视觉巡检小车:自主避障与目标追踪实现全解析

本文基于 ESP32-CAM 实现了低成本 AI 视觉巡检小车的核心功能,硬件成本<100 元,兼顾自主避障与目标追踪。算法升级:移植 YOLOv5nano 量化模型(INT8),提升目标检测精度(如识别巡检场景中的 “异常物体”“人员”);无线拓展:通过 MQTT 协议将巡检图像、距离数据上传到阿里云 / 腾讯云,实现远程监控;多传感器融合:增加温湿度(DHT11)、红外测温(MLX90614)模块,扩展巡检维度;路径规划:结合 SLAM 算法,实现自主建图与路径巡检。

weixin_42300449的博客 368

Python3 使用psycopg2模块 批量写入数据到PostgreSQL数据库(最强输出速度,单机数据库3000W数据写入最多180秒)

Python3 使用psycopg2模块 批量写入数据到PostgreSQL数据库(最强输出速度,单机数据库3000W数据写入最多3分钟) 1.本文知识点 1)将string或者list类型的数据转换为IO缓冲区中的str类型(指定格式) 2)利用PostgreSQL中的copy_from 和copy_to函数将IO缓冲区中的str类型数据写入数据库中。 2.使用方法 1)写入数据类型为list时 ''' 功能:将list数据类型多条记录一次写入数据库中 数据示例:[[1, 2, 3, 4, 5, 6, 7

ispringmw的博客 5065

UG NX二次开发(C++)-库缺少需要的入口点的原因与解决方案

在UG NX二次开发过程中,有时会遇到形形色色的bug,比如有个读者其采用UG NX二次开发(C++)时,遇到“库缺少需要的入口点”这个问题,看了一下他发给我的源代码,感觉有必要讲一下UG NX二次开发(C++)遇到此类问题的可能情况与解决方法。自然,这是博主的经验之谈,有不足之处还请在评论区讨论。

GimiGimmy 2204

Stable Diffusion WebUI 安装前准备

大家好,我是水滴~~在安装 stable-diffusion-webui 前需要做一些准备工作,本篇文章主要介绍需要的电脑配置、魔法、安装 Python、安装 Git 等。

水滴的博客 2102

PostgreSQL 16 技术深解:主流程、源码剖析与业务应用

PostgreSQL 16 在并行化、标准化、监控、权限、工具链等方面实现了全面升级。其主流程设计强调高效利用硬件、丰富标准兼容、细粒权限控制和便捷可观测性。通过源码剖析和流程图,我们可知其关键环节的实现机制与优化方向。结合实际业务场景、调试技巧和高阶集成方案,PostgreSQL 16 能为企业级应用、大数据分析、云原生架构提供坚实支撑。知其然,更知其所以然——理解 PostgreSQL 16 的设计哲学与实现细节,是高效开发、运维和架构演进的基石。

IT技术学习与工作笔记分享 2086

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

postgresql批量插入数据脚本_asp.net实现Postgresql快速写入/读取大量数据实例

最近因为一些项目需要大量插入数据,研究了下asp.net实现Postgresql快速写入/读取大量数据,所以留个笔记环境及测试使用.net驱动npgsql连接post数据库。配置:win10 x64, i5-4590, 16G DDR3, SSD 850EVO.postgresql 9.6.3,数据库与数据都安装在SSD上,默认配置,无扩展。CREATE TABLE public.mesh(x i...

weixin_39870664的博客 733

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

高速向 postgreSQL数据库中写入数据

向postgreSQL数据表中写入数据有多种方法,这里记录效率相对比较高的两种。

domodo2012的博客 1648

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Python批量写入数据到PostgreSQL性能对比

本文对比了Python写入PostgreSQL的三种主流方案:executemany()批量插入、COPY命令和pandas.to_sql()。测试结果显示,COPY命令性能最优(19,500条/秒),是基础方案的2.4倍。文章还探讨了预处理语句和多线程写入等进阶优化方法,其中多线程COPY可达28,000条/秒。针对不同场景,给出了百万级数据优先使用COPY命令、千万级数据采用多线程COPY等具体建议,并提供了关键性能调优参数。最终指出应根据数据特征选择方案,并通过持续监控实现最优性能。

得塔云的博客 1051

PostgreSQL迁移实战:从SQLite到生产级数据库的平滑演进

PostgreSQL迁移实战:从SQLite到生产级数据库 摘要:本文记录了将跑步教练AI项目从SQLite迁移到PostgreSQL的完整过程。针对SQLite在高并发场景下的三大痛点(并发写入锁死、缺乏异步支持、数据类型宽松),我们采用PostgreSQL+SQLAlchemy 2.0异步ORM方案,通过重构数据库会话管理、改造所有CRUD操作为异步模式、处理严格类型检查等关键步骤,实现了零数据丢失的平滑迁移。迁移后系统并发处理能力提升10倍以上,完美支持FastAPI的异步特性。文中包含具体代码示例和

让技术为我所用 1923

PostgreSQL - 常用监控指标:连接数、负载、IO 监控

PostgreSQL监控摘要 PostgreSQL作为核心数据库组件,其性能直接影响系统稳定性。本文重点介绍三大关键监控维度: 连接数监控:通过pg_stat_activity视图跟踪连接状态,特别关注idle in transaction等危险状态。提供Java代码示例实现连接数检查,包括总连接数、最大连接数和异常连接检测。 负载监控:分析CPU、内存等系统资源使用情况,识别性能瓶颈。 IO监控:监控磁盘读写性能,预防存储瓶颈。 文章强调主动监控的重要性,提供实用SQL查询和Java实现,帮助开发者构建数

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

Python读取MongoDB数据并写入PostgreSQL

使用Python 3读取MongoDB数据,然后写入到PostgreSQL中,分别借助pymongo和psycopg2库。 经整理和优化后以分批次读取和写入的方式较适合生产场景,并能有效应对数据量比较大的情况。

XuXuemin的专栏 379

Pathway 实时非结构化数据管道实战:用 LLM 将金融财报 PDF 结构化写入 PostgreSQL

本指南基于 Pathway Live Data Framework 的「unstructured-to-structured」模板思路,讲解如何用一条**实时、增量、可持续运行**的数据管道,把散落在 PDF、Word、网页等非结构化文档中的金融数据自动抽取并结构化:先读取 PDF 原文,再用 LLM 提取财务字段并生成表格,最终写入 PostgreSQL,且当源文件更新时结果能自动保持最新。读完

gitblog_00468的博客 478

从一次‘Fsync Bug’争议说起:聊聊PostgreSQL Heap表写入与Linux内核IO的那些‘爱恨纠葛’

本文深入探讨了PostgreSQL Heap表写入机制与Linux内核IO子系统的复杂互动,特别是围绕2018年‘Fsync Bug’争议展开分析。文章详细解析了Heap表的物理结构、写入流程,以及Linux内核Page Cache与数据库持久化保证之间的冲突,为高可靠存储系统设计提供了宝贵经验。

weixin_30631587的博客 143

高效批量数据写入:PostgreSQL COPY 协议实战指南

PostgreSQL COPY协议批量数据写入实战指南 摘要:针对PostgreSQL批量写入大量数据时遇到的参数数量限制问题,本文介绍了使用COPY协议的高效解决方案。COPY协议采用二进制格式直接传输数据,避免了SQL解析开销,可实现百万级数据无分片写入,同时保持事务安全和低内存占用。文章详细讲解了COPY协议原理,并提供了Go语言实现代码和完整测试用例,包括数据验证、事务管理和性能对比。相比传统分批插入,COPY协议在20000条数据测试中展现出显著性能优势,具备更低的内存占用和更少的网络请求次数。

ezreal_pan的博客 755
上一篇: PostgreSQL笔记24: Background Writer 后台写进程的原理、参数调优与可观测性演进
下一篇: PostgreSQL笔记26:MVCC多版本并发控制机制深度解析
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值