当前位置: 首页 > news >正文

postgresql-重复执行相同语句,试试 prepare!

文章目录


每次你向 PostgreSQL 发送 SQL 语句时,数据库都必须对其进行解析(parse)。解析虽然很快,但如果同样的语句被解析一千次,这种操作累积起来可能会占用大量时间,而这些时间本可以用于处理其他事务。为避免这种情况,PostgreSQL 提供了 prepare 语句。通过使用它,你可以避免重复解析语句,数据库只需执行planning和execution操作。

为了生成一些示例数据,这里使用了scale factor(规模因子)为 100 的 pgbench,这在 pgbench_accounts 表中产生10,000,000 行:

bench=#pgbench -U dbmgr -h 127.0.0.1 -p 5432 -i -s 100 bench
Password: 
dropping old tables...
NOTICE:  table "pgbench_accounts" does not exist, skipping
NOTICE:  table "pgbench_branches" does not exist, skipping
NOTICE:  table "pgbench_history" does not exist, skipping
NOTICE:  table "pgbench_tellers" does not exist, skipping
creating tables...
generating data (client-side)...
10000000 of 10000000 tuples (100%) done (elapsed 19.54 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done in 29.01 s (drop tables 0.00 s, create tables 0.02 s, client-side generate 20.19 s, vacuum 0.70 s, primary keys 8.09 s).
postgres@pgrec-d:~psql bench
psql (15.5 (Ubuntu 15.5-1.pgdg22.04+1))
Type "help" for help.bench=# select count(*) from pgbench_accounts;count  
----------10000000
(1 row)bench=# d pgbench_accountsTable "public.pgbench_accounts"Column  |     Type      | Collation | Nullable | Default
----------+---------------+-----------+----------+---------aid      | integer       |           | not null | bid      | integer       |           |          | abalance | integer       |           |          | filler   | character(84) |           |          | 
Indexes:"pgbench_accounts_pkey" PRIMARY KEY, btree (aid)

简单query一下:

bench=# select count(*) from pgbench_accounts where aid = 11111;count
-------1
(1 row)

正如本文开头所述,PostgreSQL 将需要解析该语句。使用带有正确选项的 explain,您可以看到产生执行计划花费了多少时间:

                                                                    QUERY PLAN                                                                     
---------------------------------------------------------------------------------------------------------------------------------------------------Aggregate  (cost=4.46..4.46 rows=1 width=8) (actual time=0.041..0.042 rows=1 loops=1)Buffers: shared hit=4->  Index Only Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.43..4.45 rows=1 width=0) (actual time=0.030..0.032 rows=1 loops=1)Index Cond: (aid = 11111)Heap Fetches: 0Buffers: shared hit=4Planning Time: 0.125 msExecution Time: 0.086 ms
(8 rows)

产生此语句的执行计划比执行它花费更多时间。现在假设您要执行同一条语句一千次:

bench=#\t
bench=#select 'select count(*) from pgbench_accounts where aid = 11111;' from generate_series(1,1000) i; \g test.sql
bench=# \! cat test.sql | head
select count(*) from pgbench_accounts where aid = 11111;
select count(*) from pgbench_accounts where aid = 11111;
select count(*) from pgbench_accounts where aid = 11111;
select count(*) from pgbench_accounts where aid = 11111;
select count(*) from pgbench_accounts where aid = 11111;
select count(*) from pgbench_accounts where aid = 11111;
select count(*) from pgbench_accounts where aid = 11111;
select count(*) from pgbench_accounts where aid = 11111;
select count(*) from pgbench_accounts where aid = 11111;
select count(*) from pgbench_accounts where aid = 11111;
...

当执行该命令时,强制 PostgreSQL解析所有这 1000 条语句:

bench=# \timing
Timing is on.
bench=#\! /usr/bin/time -p psql -U dbmgr -f test.sql -d bench
real 0.76s
user 0.13s
sys 0.1s

为了避免这种情况,我们使用prepare去准备这条sql:

prepare c1 as select count(*) from pgbench_accounts where aid = 11111;
PREPARE

一旦prepare好,就可以执行它:

bench=# execute c1;count
-------1
(1 row)

explain:

bench=# explain(analyze,buffers) execute c1;Aggregate  (cost=4.46..4.46 rows=1 width=8) (actual time=0.041..0.042 rows=1 loops=1)Buffers: shared hit=4->  Index Only Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.43..4.45 rows=1 width=0) (actual time=0.030..0.032 rows=1 loops=1)Index Cond: (aid = 11111)Heap Fetches: 0Buffers: shared hit=4Planning Time: 0.007 msExecution Time: 0.100 ms

注意,与未准备好的语句相比,planning time减少了不少:

bench=# explain(analyze,buffers) select count(1) from pgbench_accounts where aid=11111;Aggregate  (cost=4.46..4.46 rows=1 width=8) (actual time=0.076..0.077 rows=1 loops=1)Buffers: shared hit=4->  Index Only Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.43..4.45 rows=1 width=0) (actual time=0.057..0.059 rows=1 loops=1)Index Cond: (aid = 11111)Heap Fetches: 0Buffers: shared hit=4Planning:Buffers: shared hit=3Planning Time: 0.376 msExecution Time: 0.166 ms

当现在这样执行一千次:

bench=# \t
Tuples only is off.
bench=# select 'execute c1;' from generate_series(1,1000) i; \g test.sql
bench=# \! sed -i '1s/^/prepare c1 as select count(*) from pgbench_accounts where aid = 11111;/' test.sql
bench=# \! /usr/bin/time -p psql -U dbmgr -f test.sql -d bench
real 0.55s
user 0.11s
sys 0.15s

执行时间将会缩短。在这个简单的例子中,效果不太明显,但这是因为语句本身非常简单。顺便提一下,预编译的语句只在会话期间有效,所以 sed 命令将 prepare 语句添加到文件顶部,预编译本身也需要时间。如果不预编译,执行时间会更短。
当 where 子句中的值发生变化时,可以这样做:

bench=# prepare c1 as select count(*) from pgbench_accounts where aid = $1;
PREPARE
Time: 0.387 ms

解除prepare好的语句

bench=# deallocate c1;
DEALLOCATE
Time: 0.336 ms

相关文章:

postgresql-重复执行相同语句,试试 prepare!

文章目录 每次你向 PostgreSQL 发送 SQL 语句时,数据库都必须对其进行解析(parse)。解析虽然很快,但如果同样的语句被解析一千次,这种操作累积起来可能会占用大量时间,而这些时间本可以用于处理其他事务。为避免这种情况&#xff…...

wpf加载带材料的3D模型(下载的3D预览一样有纹理)

背景:最近真的是忙啊,累出汁水了 整体效果: 放大可以看清砖头: 1、需要自己准备好3D模型,比如我这里是下载的这里的3D Warehouse,下载Collada File格式文件 2、解压可以看到一个model.dae和材料的文件夹&…...

【k8s之深入理解调度】调度框架扩展点理解

参考自 K8s 调度框架设计与 scheduler plugins 开发部署示例(2024) 调度插件扩展点 等待调度阶段PreEnqueuePod 处于 ready for scheduling 的阶段。 内部工作原理:sig-scheduling/scheduler_queues.md。在 Pod 被放入调度队列之前执行的插…...

音视频基础理论

1. 音频基础 1.1 音频基本概念 1.1 频率:声波的频率,即声音的音调,人类听觉的频率(音调)范围为20Hz--20KHz 1.2 振幅:即声波的响度,通俗的讲就是声音的高低,一般男生的声音振幅(响度)大于女生。 1.3 波形…...

《江苏科技大学学报(自然科学版)》

《江苏科技大学学报(自然科学版)》(双月刊,国内外公开发行)是由江苏省教育厅主管、江苏科技大学主办的理工类学术期刊,1986年创刊,国际刊号:ISSN1673-4807,国内刊号&…...

C++初学者指南-5.标准库(第二部分)–随机数生成

C初学者指南-5.标准库(第二部分)–随机数生成 文章目录 C初学者指南-5.标准库(第二部分)–随机数生成基本概念例子统一随机数布尔值(“抛硬币”)正态分布具有独立概率的整数 怎么做种子引擎使用自定义生成器 shuffle算法分布类型概述通用接口均匀分布采样…...

Unity2017在安卓下获取GPS位置时闪退的解决办法

在Unity使用低功耗蓝牙通信(BLE)需要用到设备的位置信息。但是调用Input.location.Start()程序会闪退。 解决办法:调用原生安卓接口。 参见《Unity2021通过aar调用Android方法》编写一个aar插件gpsplugin,在插件中提供获取GPS位…...

OpenGL ES 索引缓冲区(4)

OpenGL ES 索引缓冲区(4) 简述 本节会介绍索引缓冲区,索引缓冲区和顶点缓冲区类似,也是显存上的一段内存,只不过上面的数据用处不同,索引缓冲区故名思义里面的数据是用于索引,主要作用是用于复用顶点缓冲区里的数据。…...

01:(寄存器开发)点亮一个LED灯

寄存器开发 1、单片机的简介1.1、什么是单片机1.2、F1系列内核和芯片的系统架构1.3、存储器映像1.4、什么是寄存器 2、寄存器开发模板工程3、使用寄存器点亮一个LED4、代码改进15、代码改进2 本教程使用的是STM32F103C8T6最小系统板,教程来源B站up“嵌入式那些事”。…...

.Net 6.0 Windows平台如何判断当前电脑是否联网

最近在工作中开发需要判断当前电脑是否联网的需求,在网上找了一个调用window API来判断本机是否联网。具体请看下面介绍: 1.方法一(调用winAPI) [DllImport("wininet")] public static extern bool InternetGetConnec…...

微软准备了 Windows 11 24H2 ISO “OOBE/BypassNRO“命令依然可用

Windows 11 24H2 可能在未来几周内开始推出。 微软已经要求 OEM 遵循新的指南准备好 Windows 11 24H2 就绪的驱动程序,并且现在已经开始准备媒体文件 (.ISO)。 OEM ISO 的链接已在微软服务器上发布。 一个标有"X23-81971_26100.1742.240906-0331.ge_release_sv…...

MacOS 终端执行安装 Brew

在配置新的 Mac 环境时,如果你发现终端中无法识别 brew 命令,可以按照以下步骤进行解决。 步骤 1:确保网络稳定 为了避免安装过程中出现中断,建议使用 Wi-Fi 或有线连接,不推荐使用移动网络。 步骤 2:打…...

【设计模式-解释模式】

定义 解释器模式是一种行为设计模式,用于定义一种语言的文法,并提供一个解释器来处理该语言的句子。它通过为每个语法规则定义一个类,使得可以将复杂的表达式逐步解析和求值。这种模式适用于需要解析和执行语法规则的场景。 UML图 组成角色…...

51单片机应用开发(进阶)---数码管+按键+蜂鸣器(电磁炉显示模拟)

实现目标 1、加强数码管、按键的学习,实现数码显示变量数据(四位数的显示); 2、4位数码2个按键无源蜂鸣器实现模拟电磁炉功率调节及显示; 一、内容描述 功能描述:1、开机显示电磁炉功率300,每…...

Emergency Stop (ES)

文章目录 1. 介绍2. Feature List3. 紧急停止信号触发方式3.1 Port触发紧急停止信号3.2 SMU事件触发紧急停止信号3.3 软件触发紧急停止信号 4. 应用场景4.1 Port4.2 MSC 1. 介绍 Emergency Stop (ES)是Ifx System Control Units (SCU)六大模块之一。详细信息可以参考Infineon-…...

[C++][第三方库][gtest]详细讲解

目录 1.介绍2.安装3.使用1.头文件包含2.框架初始化接口3.调用测试样例4.TEST宏5.断言宏6.示例 1.介绍 gtest是一个跨平台的C单元测试框架,由Google公司发布gtest是为了在不同平台上为编写C单元测试而生成的,它提供了丰富的断言、致命和非致命判断、参数…...

【Java数据结构】 链表

【本节目标】 1. ArrayList 的缺陷 2. 链表 3. 链表相关 oj题目 一. ArrayList的缺陷 上节课已经熟悉了ArrayList 的使用&#xff0c;并且进行了简单模拟实现。通过源码知道&#xff0c; ArrayList 底层使用数组来存储元素&#xff1a; public class ArrayList<E>…...

前端——Ajax和jQuery

一、Ajax Ajax即“Asynchronous Javascript And XML”&#xff08;异步 JavaScript 和 XML&#xff09;&#xff0c; 通过 JS 异步的向服务器发送请 求并接收响应数据。 同步访问&#xff1a;当客户端向服务器发送请求时&#xff0c;服务器在处理的过程中&#xff0c;浏览器…...

C++-vector模拟实现

###vector底层相当于是数组&#xff0c;查看源码可以发现&#xff0c;这个类的私有成员变量是三个迭代器&#xff1b;在实现时迭代器就可以当作是vector里面的元素的指针类型&#xff1b; ###vector是一个类模板&#xff0c;实现时也应当按照这样的写法用一个模板去实现&#…...

Activity

69[toc] 1.启停活动页面 1.Activity启动和结束 从当前页面跳到新页面 startActivity(new Intent(this, ActFinishActivity.class));从当前页面返回上一个页面&#xff0c;相当于关闭当前页面 finish();2.Activity生命周期 官方描述生命周期 onCreate&#xff1a;创建活…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

鸿蒙HarmonyOS 5军旗小游戏实现指南

1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;采用DevEco Studio实现&#xff0c;包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...