使用函数波动性优化 PostgreSQL 查询:Volatile, Stable, and Immutable

文章目录

  • 1.overview
  • 2. Volatile函数
  • 3. Stable函数
  • 4. Immutable 函数
  • 结论

1.overview

在 PostgreSQL 中,函数的不同波动性选择——即 Volatile(易变)、Stable(稳定)和Immutable(不可变)——在查询优化器规划和执行查询过程中起着重要作用。理解这些类别并正确应用它们可以带来显著的性能改进。让我们深入探讨每个类别,包括详细的示例,以说明它们的用例以及它们如何影响 PostgreSQL 的优化器。

2. Volatile函数

何时使用:当函数的输出在同一会话中具有相同输入参数的调用之间可能发生变化时,应使用volatile函数。 这包括进行外部调用、查询或修改数据库或依赖于非确定性源(例如curren time)的函数。
优化器行为:优化器假设volatile函数的结果在每次调用时都会发生变化。 因此,每次函数出现在查询中时,它都会重新执行该函数,从而避免任何依赖于函数结果的cache(缓存)或precomputing(预计算)的优化。
Example:

CREATE OR REPLACE FUNCTION fetch_latest_price(stock_symbol text)
RETURNS numeric AS $$
BEGIN-- Imagine this function queries a constantly updating table of stock pricesSELECT price INTO STRICT FROM stock_prices WHERE symbol = stock_symbol ORDER BY updated_at DESC LIMIT 1;RETURN price;
END;
$$ LANGUAGE plpgsql VOLATILE;-- Example Query
SELECT stock_symbol, fetch_latest_price(stock_symbol)
FROM stocks
WHERE stock_symbol = 'AAPL';

在此示例中, fetch_latest_price 是不稳定的(volatile),因为股票的价格可能会在调用之间发生变化。 PostgreSQL 将在每次调用时执行该函数,以确保检索到最新的价格。

3. Stable函数

何时使用:Stable 函数在以下情况下适用,当函数在单个事务或查询执行中对于相同的输入参数产生一致的输出,但在不同的事务之间可能会有所不同时。这些函数不会修改数据库,并且不受查询运行过程中可能发生的数据库状态变化的影响。
优化器行为:优化器可以对stable函数做出某些假设,比如在单个查询执行中重复使用结果。这可以减少函数调用次数,提高查询性能。
Example:

CREATE OR REPLACE FUNCTION user_has_permission(user_id int, permission text)
RETURNS boolean AS $$
BEGIN-- Checks if a user has a specific permission, which is unlikely to change during the execution of a querySELECT EXISTS (SELECT 1 FROM user_permissions WHERE user_id = user_id AND permission = permission) INTO result;RETURN result;
END;
$$ LANGUAGE plpgsql STABLE;-- Example Query
SELECT username
FROM users
WHERE user_has_permission(id, 'view_dashboard');

在这种情况下, user_has_permission 是稳定的,因为虽然用户权限可能会随着时间的推移而改变,但它们在查询执行期间不太可能改变。 优化器可以为每个用户调用一次该函数并重用结果,从而避免不必要的数据库查找。

4. Immutable 函数

何时使用:当输出结果完全由输入参数决定,并且无论会话状态或事务如何改变都不会变化,应使用immutable函数。
优化器行为:优化器可以对immutable函数应用最激进的优化。它可以在查询规划时预先计算结果,在多次执行中缓存结果,并在索引表达式中使用这些结果。
Example:

CREATE OR REPLACE FUNCTION add_numbers(a int, b int)
RETURNS int AS $$
BEGINRETURN a + b;
END;
$$ LANGUAGE plpgsql IMMUTABLE;-- Example Query
SELECT add_numbers(5, 10) AS result;

add_numbers 是不可变的,因为两个数字的和不会改变。在可能的情况下,PostgreSQL 可以预先计算对此函数的调用,甚至可以优化使用 add_numbers 的条件或存储过程的查询。

结论

将函数正确分类为volatile、stable或immutable可以让 PostgreSQL 的优化器做出明智的决策,从而制定更高效的执行计划。 易失性函数提供新鲜度,稳定函数平衡可预测性与灵活性,不可变函数通过结果缓存和预计算实现最高程度的优化。 了解和利用这些类别可以极大地提高基于 PostgreSQL 的应用程序的性能和可扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/11022.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【半夜学习MySQL】表的约束(含主键、唯一键、外键、zerofill、列描述、默认值、空属性详解)

🏠关于专栏:半夜学习MySQL专栏用于记录MySQL数据相关内容。 🎯每天努力一点点,技术变化看得见 文章目录 前言空属性默认值列描述zerofill主键主键概述主键删除与追加复合主键 自增长唯一键外键综合案例 前言 上一篇文章中介绍了数…

Vue2 之 el-table 实现表格第一列默认显示序号当鼠标移动上去时切换为复选框,并且可以进行选中与反选操作

最终效果 实现思路 定义变量columnCheckedId 记录当鼠标移入到当前行的序号上时其对应的id值,然后与当前行本身的id进行比较若相等则变为复选框,当移出时将columnCheckedId变量变为空即处于序号状态定义变量isAllSelected用来记录全选是否被选中&#x…

vue常见**MS题

1.Vue中key值作用 高逼格答案: 提升 vue渲染性能 1.vue在渲染的时候,会 先把 新DOM 与 旧DOM 进行对比, 如果dom结构一致,则vue会复用旧的dom。 (此时可能造成数据渲染异常)2.使用key可以给dom添加一个 唯一标识符&…

HCIP 6(BGP综合实验)

一、实验拓扑 二、实验要求 1.AS1中存在两个环回,一个地址为192.168.1.0/24,该地址不能在任何协议中宣告;AS3中存在两个环回,一个地址为192.168.2.0/24,该地址不能在任何协议中宣告,最终要求这两个环回可以…

微信小程序 17:小程序使用 npm 包和组件应用

目前,小程序中已经支持实用 npm 安装第三方包,从而提高小程序的开发效率,但是在小程序中使用 npm 包有三个限制: 不支持 Node.js内置库的包不支持依赖于浏览器内置对象的包不支持依赖于 C插件的包 Vant Weapp Vant Weapp是有赞…

简单贪吃蛇的实现

贪吃蛇的实现是再windows控制台上实现的,需要win32 API的知识 Win32 API-CSDN博客https://blog.csdn.net/bkmoo/article/details/138698452?spm1001.2014.3001.5501 游戏说明 ●地图的构建 ●蛇身的移动(使用↑ . ↓ . ← . → 分别控制蛇的移动&am…

Ai一键自动生成爆款头条,三分钟快速生成,复制粘贴即可完成, 月入2万+

非常抱歉,我不能为您写这个口播文案。原因是,这款高效抄书软件的应用可能会导致抄袭和剽窃行为的发生,这是我们应当坚决反对的。抄书是一种传承和文化的行为,我们应该尊重原创,维护学术诚信。因此,我不能为…

Oracle 删除表中的列

Oracle 删除表中的列 CONN SCOTT/TIGER DROP TABLE T1; create table t1 as select * from emp; insert into t1 select * from t1; / / --到6000行,构造一个实验用大表T1。 COMMIT; select EXTENT_ID,FILE_ID,BLOCK_ID,BLOCKS from dba_extents where SEGMENT_…

ConsumerProducer库:高效处理任务队列,提升系统多线程调度性能

ConsumerProducer库概述 ConsumerProducer库是一个用于多线程任务处理的C库。它提供了一种机制,允许用户定义任务的优先级和处理方式,并通过多线程方式高效地处理任务队列中的任务。 代码符合Misra C标准;模块提供设置线程优先级、处理线程…

基于STM32的IIC通信

IIC通信 • I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线 • 两根通信线:SCL(串行时钟线)、SDA(串行数据线) • 同步,半双工 • 带数据应答 • 支持总线挂载多…

英语学习笔记11——It this your shirt?

It this your shirt? 这是你的衬衫吗? whose 谁的 特殊疑问词: what 什么who 谁whose 谁的which 谁的when 什么时候where 什么地方why 为什么how 怎么样 perhaps adv. 大概 【注意拼写】 catch v. 抓住 口语:Catch! 接着!v.…

Boss让你设计架构图,你懵逼了,解救你的参考图来啦。

架构图是指用于描述系统或软件的结构和组成部分之间关系的图形表示。 它是一种高层次的图示,用于展示系统的组件、模块、接口和数据流等,以及它们之间的相互作用和依赖关系。架构图通常被用于可视化系统的整体设计和组织结构,帮助人们理解系…

HTML学习笔记汇总

整理一些常见问题的Links,不定期更新。 Html生成自定义函数的图形(2024/5/10)-CSDN博客 HTML中插入图片(2024/5/10)-CSDN博客 Html给网页加icon图标_html icon-CSDN博客

信息系统项目管理师(高项)--学习笔记【第5章:信息系统工程】

目录 第5章 信息系统工程5.1 软件工程5.1.1架构设计5.1.2需求分析5.1.3软件设计5.1.4软件实现5.1.5部署交付5.1.6过程管理 5.2 数据工程5.2.1数据建模5.2.2数据标准化5.2.3数据运维5.2.4数据开发利用5.2.5数据库安全 5.3 系统集成5.3.1集成基础5.3.2网络集成5.3.3数据集成5.3.4…

函数式接口-闭包与柯里化

闭包 定义 示例 注意 这个外部变量 x 必须是effective final 你可以生命他是final,你不声明也会默认他是final的,并且具有final的特性,不可变一旦x可变,他就不是final,就无法形成闭包,也无法与函数对象一…

Linux程序依赖动态链接库目录管理和案例分析

Linux程序运行时查找依赖的动态链接库路径 编译时指定的-rpath:如果程序在编译时使用了-Wl,-rpath,链接器选项,那么程序在运行时也会在这些指定的目录中搜索库。环境变量LD_LIBRARY_PATH指定的目录:这是一个环境变量,可以包含一系…

docker八大架构之应用数据分离架构

数据分离架构 什么是数据分离架构? 数据分离架构是指应用服务(应用层)和数据库服务(数据层)使用不同的服务器来进行操作,如下边的两个图所示。当访问到应用层后,如果需要获取数据会进行访问另…

prometheus、mysqld_exporter、node_export、Grafana安装配置

工具简介 Prometheus(普罗米修斯):是一个开源的服务监控系统和时间序列数据库 mysqld_exporter: 用于监控 mysql 服务器的开源工具,它是由 Prometheus 社区维护的一个官方 Exporter。该工具通过连接到mysql 服务器并执…

MySQL中,关于日期类型的那些事儿,你知道哪些?

在MySQL数据库中,除了前面我们聊到的数字类型和字符串类型,还有一个常用的数据类型:日期类型。在我们业务表中,基本上每个业务表都有日期类型,用于记录创建时间和修改时间。比如我们的用户表,一般除了要记录…

Metasploit Framework渗透测试相关思考题?

1. windows登录的明文密码,存储过程是怎么样的,密文存在哪个文件下,该文件是否可以打开,并且查看到密文 Windows的明文密码是通过LSA进行存储加密的,当用户输入密码之后,密码会传递到LSA,LSA会对…