2026/4/18 13:58:00
网站建设
项目流程
自己做家装设计网站,平面设计师网上接单,广州统一企业官网建设,做网站行情原文地址 https://postgresql.verite.pro/blog/2025/10/01/psql-pipeline.html
psql 中的流水线操作#xff08;PostgreSQL 18#xff09;
2025 年 10 月 1 日
Postgres 中的流水线是什么#xff1f;
流水线是网络协议支持的一种客户端特性#xff0c;其核心思想是#xf…原文地址 https://postgresql.verite.pro/blog/2025/10/01/psql-pipeline.htmlpsql 中的流水线操作PostgreSQL 182025 年 10 月 1 日Postgres 中的流水线是什么流水线是网络协议支持的一种客户端特性其核心思想是在发送下一条查询前无需等待之前已发送查询的结果返回。这种方式通过两种途径提升吞吐量客户端、网络和服务器可以并行工作。例如网络可能在传输第 (N-1) 条查询结果的同时服务器正在执行第 N 条查询而客户端正在发送第 (N1) 条查询——所有这些操作同时进行。网络利用率更高因为连续的查询可以被分组到相同的网络数据包中从而减少总体数据包数量。流水线功能自 7.4 版本2003 年发布引入扩展查询协议后便成为可能。但直到 2021 年 PostgreSQL 14 发布才可以通过客户端 C 库 libpq 使用该功能。此后一些基于 libpq 的驱动程序如 psycopg3开始支持流水线。上周发布的 PostgreSQL 18 中命令行客户端 psql 新增了在 SQL 脚本中使用流水线操作的命令使其变得更加易用。虽然这一新增功能并非该版本的突出特性但它能显著提升查询吞吐量我们将在下面的简单测试中看到这一点。psql 命令流水线操作以\startpipeline开始在最简单的情况下其后跟随 SQL 查询并以\endpipeline结束。如果需要中间结果可以使用\syncpipeline强制设置一个同步点并使用\getresults获取到该点为止的所有结果。此外启动流水线会创建一个隐式事务。如果某个查询失败自开始或上一个同步点以来的所有更改都将被回滚。如果你了解使用\;语法将多个查询分组到同一请求中的技术那么它与流水线操作有相似之处两者都用于减少服务器往返次数并且在事务方面具有相同的语义。从某种意义上说流水线操作是扩展查询协议中对简单查询协议中多语句查询psql 中的\;的演进。性能测试我们做一个简单的测试使用INSERT ... ON CONFLICT查询导入设备数据。对于同一设备、同一日期的情况会更新行否则插入新行。需要注意的是如果我们想无条件追加所有行使用COPY会更合适流水线操作则非必需因此本次测试选择了更复杂的插入或更新操作。以下 bash 代码根据参数决定是否使用流水线来导入随机生成的数据。functionimport_data{localcount$1# 导入多少行localpipeline$2# 1 或 0localnow_ts$(date%s)(echoPREPARE s AS insert into events(device, recorded_at, measure) values($1, to_timestamp($2), $3) on conflict(device,recorded_at) do update set measureexcluded.measure;echoBEGIN;[[$pipeline1]]echo\\startpipelineforiin$(seq1$count)dodevice$RANDOMsecs$(($now_ts$RANDOM*50))measure${RANDOM}.${RANDOM}echoexecute s($device, $secs,$measure);done[[$pipeline1]]echo\\endpipelineechoCOMMIT;)|$psql-q -vON_ERROR_STOP1}让我们尝试以 100、1000、5000、10000、50000、100000 行为批次分别使用和不使用流水线操作并比较这些批次的处理速度。此外由于网络速度在此处影响很大我们将在三种典型的网络连接下进行测试本地主机ping 时间约 0.04ms客户端和服务器在同一主机上。局域网ping 时间约 1ms客户端和服务器仅通过一个 1GB/s 的以太网交换机连接。广域网ping 时间约 4ms服务器通过公共互联网连接访问。最后每种情况运行 5 次我们只取运行时间的中位数。![本地主机性能对比图]在同一主机上流水线带来的加速效果从最小批次的 1.5 倍到最大批次的 5 倍不等。![局域网性能对比图]在局域网连接上最小批次的加速效果是 2.6 倍而较大批次则高达 42 倍。![广域网性能对比图]在最慢的网络广域网上效果更加显著。加速比在 5.4 倍到 71 倍之间结论这些加速效果表明在没有流水线操作的情况下当我们发送小查询批次时网络利用率是多么不足网络数据包就像载客 50 人的巴士每次却只载着一位乘客行驶。在我们的示例中为了在这方面进行优化我们只需添加一对\startpipeline和\endpipeline命令。这是因为我们的查询不依赖于同一批次中先前查询的结果除非一个查询失败导致整个批次失败的情况。如果没有流水线操作我们仍然可以通过在每条查询的VALUES子句中添加多行数据而不是每查询一行来优化测试。但找到每个查询应包含多少数据行的最佳平衡点并不容易而且带有数千个参数的大型查询在服务器端处理起来也并非易事。此外如果客户端逻辑更复杂例如有条件地操作多个表那么在流水线中运行简单语句同时使用逐行逻辑可能会容易得多。流水线元命令是在 psql 18 版本中添加的但它们并不要求服务器端必须是 PostgreSQL 18。对于那些对此功能感兴趣但暂时无法升级服务器的人您仍然可以升级到最新版本的 psql它在尽可能保持向后兼容性。