[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

这篇具有很好参考价值的文章主要介绍了[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

再次声明:

并不是所有场景都需要(或者适合)用rust来写的,绝大部分操作数据库的功能和计算,用SQL就已经足够了!

本系列中,所有的案例,仅用于说明pgrx的能力,而并非是说这样做比用SQL更合适。反之:对于操作数据库本身的部分,大部分能用SQL来实现的东西,都比做一个扩展开发要更加合适。

——如果哪位大神写Rust走火入魔,说啥数据库功能都要用Rust来扩展实现的,不报我的名字,你们打成半死就行,报我的名字,请打成八成死。

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

单值输入与输出函数

这里的单值,是针对序列这种多值类型而言的。

SQL做为第四代语言,与第三代语言最大的区别,就是尽量舍弃了所谓的计算机思维,即for和if。

例如我们在高级语言里面对一批数据要进行查询或者筛选,必须是按照计算机的思维方式来进行:

例如老板说,我们准备找出大于35岁的同学,以向社会进行输送,那么程序员要实现这个想法,就得这样思考和实现问题: 对整个数据集进行一个个的迭代,然后一个个的比较,如果满足条件,就进行社会输出……

for row in dataset:
    if row['age'] > 35:
        row["结果"] = "输送社会"
    else:
        row["结果"] = "在用几年"

但是SQL里面,要实现这个功能,则不会有for和if这类语句:

select * from dataset where age > 35

有正如高级语言要执行,先要被编译器编译成汇编,然后再编译成机器语言再进行执行意义,SQL要执行,实际上也要别数据库引擎编译成汇编指令和机器语言,那么依然可以是可以解读为for和if的。

例如,我们写了这样一个数据库扩展:

#[pg_extern]
fn age_add(age:i32) -> i32 {
    age +1
}

来看看效果,非常直观:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

那么在实际使用中,比如要作用于数据库表格上的话,是什么样子呢?

先有这样一张表:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

如果我们把自定义的函数作用在这张表上的时候,就是这样的:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

可以看见,相当于对于表emps进行逐行的迭代计算,然后得到了结果。

当然,这种功能肯定没必要用扩展这种牛刀杀鸡的做法,直接用SQL就可以了:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

下面我们来做一个稍微复杂点的场景:

有如下这样一张表:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

这是一个员工信息表有五个字段,分别id,名称、加入公司的时间、生日和工资,一共是20万条记录:我用Python的faker库生成的,当然没来得及去关注入职时间和生日之间的相关关系,里面肯定有没满18岁就参加工作的问题……就不要在意这些细节了。

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

现在我们要计算一下年终奖金的系数,规则如下:

基数为2,也就是两个月工资,如果在公司超过10年,每年加1.5个点,如果不满10年,则每年1个点,不满一年的按基准算,最后用系数乘以工资,得到最后的奖金。

这个场景在业务编码里面经常见到,虽然很简单,但是包含了多条件判断、时间计算和数学计算等多种计算模型,当然……用SQL本身就很容实现,如下所示:

WITH a AS (
SELECT *,
    CASE
    WHEN date_part('year',age(now(),indate)) >= 10 
        THEN 2 + date_part('year',age(now(),indate))* 0.015

    WHEN date_part('year',age(now(),indate)) <= 1 
        THEN 2

    ELSE 2 + date_part('year',age(now(),indate))* 0.01
    END as xs
FROM tab_emps )
SELECT * ,pay*xs FROM a
LIMIT 10; 

结果如下:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

那么我们在扩展函数里面写怎么做呢? (再次强调,仅为说明能力,绝对不是建议大家这种功能小功能也动用扩展函数来牛刀杀鸡)

代码如下:

#[pg_extern]
fn cal_bonus(indate:pgrx::Date,pay:i64) -> f32{
    let now: DateTime<Local> = Local::now();
    let now_epoch = now.timestamp()/60/60/24;
    
    let x = (now_epoch as i32 - indate.to_unix_epoch_days()) / 365 ;
    
    let mut xs:f32=0.0;
    if x >=10{
        xs = 2.0 + x as f32 * 0.015;
    }
    else if x <=1 {
        xs = 2.0;
    }
    else{
        xs = 2.0 + x as f32 * 0.01;
    }
    xs * pay as f32
}

结果如下:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

可以看见二者的结果是完全一样的。

性能对比

我们来具体对比一下,使用SQL原生方式和与扩展函数两种方式,在PG上面的执行效率,我们采用EXPLAIN ANALYZE的方式来测试效率:

  1. 对于加1方法的测试:

为了复用建立出来的20万条记录的表格,所以我们需要修改一下方法: 把输入参数从i32改成i64——rust是一种强类型的语言,所以数据库中的integer和bigint是无法通用。

当然,我们也可以用泛型来做,不过既然本教程针对的是初学者,这里我就不用了,以免增加学习负担。

#[pg_extern] fn age_add(age:i64) -> i64 { age +1 }

结果如下:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

我们发现,对于20万条数据,用SQL执行加1操作,仅用了23ms,而采用扩展函数,则需要用37ms。

接下去,我们分别测试更新和插入,用两种方法,生成一张新的表格,然后在做一次更新,分别来看看性能:

CREATE AS SELECT的性能:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

依然是原生SQL性能更好

然后看看UPDATE的性能:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

三个测试的结果如下:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

然后我们再来测试一下稍微复杂点的系数与奖金计算:

查询

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

创建:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

更新 (原生SQL的子查询模式更新,实在太慢了,20万条没有执行成功,所以我把数量缩减到了1000条,也有可能是我SQL语句没写对……因为以前没有搞过子查询模式的更新这种东西,如果哪位大神写过,可以联系我……)

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

而让我感到震惊的是,使用扩展函数编写的更新,对于20万条数据,整体执行的时间如下:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

对比如下:

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

结论

  1. 简单计算和查询,SQL语言比扩展模式性能更好。
  2. 复杂计算和查询,随着数据量的变大,Rust扩展模式越发显示出优势,可能是因为在SQL里面也需要调用底层语言编写的函数,而导致转换间的性能损失吧。
  3. 如果有复杂计算且更新的需求,扩展函数的性能比原生SQL要好太多太多……可能并非是性能,而是运行机制的问题,此结论因为虾神SQL能力不行,所以不可靠。
  4. 不管是原生SQL模式还是扩展函数模式,一定都比DBC(Database Connectivity)模式要强很多很多……

待续未完。文章来源地址https://www.toymoban.com/news/detail-428778.html

到了这里,关于[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Django Web开发(day4)——数据模型使用与填充网站数据(对数据库的基本操作)

    本博客将会涉及:  Django 数据模型的使用 视频数据的导入 admin 后台的使用  1、Django 数据模型的使用  在上一篇中完成了网站的数据模型的创建,在数据模型创建之后, Django 会为我们的数据模型创建一套数据库抽象的 API 接口,以供我们进行检索数据、创建数据、更新和修

    2024年01月18日
    浏览(54)
  • 微信小程序云开发—01(云数据库、云函数的创建与基本使用)

    1. 小程序云开发,让前端程序员拥有后端的能力 2. 云函数 (nodejs) 3. 云数据库 (mogodb) 4. 云存储 5. 前端写好云函数 - 上传到云服务器 -实现自定云部署 6. 前端去调用云函数=间接通过云函数对数据库的操作 7. 前端=》全栈 1. 在app.js 2. 云函数index.js 定义id 3. 云id来自 云开发

    2024年02月15日
    浏览(46)
  • postgresql|数据库|MySQL数据库向postgresql数据库迁移的工具pgloader的部署和初步使用

    MySQL数据库和postgresql数据库之间的差异并不多,这里的差异指的是对SQL语言的支持两者并不大,但底层的东西差异是非常多的,例如,MySQL的innodb引擎概念,数据库用户管理,这些和postgresql相比是完全不同的(MySQL用户就是用户,没有角色,postgresql有用户,有角色,但差异不

    2024年02月14日
    浏览(85)
  • postgresql数据库定时备份到远程数据库

    1.老规矩,服务器目录结构: conf目录无内容 profile: 其中: 最后一行 export PGPASSWORD=‘root’ 是需要备份的数据库的密码,因为直接用 pg_dump 命令备份需要输入密码交互,而我们需要达到自动备份,所以借助这种方式不需要输入密码 docker-compose.yml: 启动容器: 然后再data目录下面

    2024年02月09日
    浏览(48)
  • 【数据库】什么是 PostgreSQL?开源数据库系统

    PostgreSQL 是一个开源的对象关系数据库系统,本文,我们将讨论 PostgreSQL、它的用途和好处。 PostgreSQL 是由 PostgreSQL Global Development Group 开发的高级 开源关系数据库管理系统(RDBMS) 。它作为 POSTGRES 项目的一部分于 1986 年在加州大学伯克利分校启动,它最初于 1996 年 7 月 8 日发布

    2023年04月08日
    浏览(48)
  • PostgreSQL Linux操作PostgreSQL数据库

    PostgreSQL教程 菜鸟教程:https://www.runoob.com/postgresql/postgresql-tutorial.html 登录PG数据库:psql -U 用户名(U需要大写) 登录PG数据库(指定主机、端口,并进入指定数据库): psql -U 用户名 -h 127.0.0.1 -p 5432 -d 数据库名 -U 登录的用户名 -h 连接的主机(默认127.0.0.1,可替换成远程主机

    2024年02月11日
    浏览(63)
  • 数据库新闻速递 -- POSTGRESQL 正在蚕食数据库市场 (翻译)

    开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请加 liuaustin3微信号 ,在新加的朋友会分到3群(共1140人左右 1 + 2 + 3) 尽管NoSQL数据库继续蓬勃发展,但关系型数据库仍

    2024年02月13日
    浏览(63)
  • [运维|数据库] docker postgresql数据库环境变量配置

    要配置Docker中的PostgreSQL数据库的环境变量,可以使用以下方法: 使用Docker命令行: 将 用户名 , 密码 , 数据库名 替换为你想要设置的实际值。这将创建一个名为 mypostgres 的容器,并将 PostgreSQL 的用户名、密码和数据库名设置为指定的值。 -p 5432:5432 指定了容器内部和主机之间

    2024年02月09日
    浏览(66)
  • PostgreSQL-数据库命令

    一个数据库是一个或多个模式的集合,而模式包含表、函数等。因此,完整的逻辑组织结构层次是服务器实例(PostgreSQL Server)、数据库(Database)、模式(Schema)、表(Table),以及某些其他对象(如函数)。一个PostgreSQL服务器实例可以管理多个数据库。当应用程序连接到一

    2024年02月14日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包