为了账号安全,请及时绑定邮箱和手机立即绑定

【原创】用第三方语言编写PostgreSQL 存储函数

标签:
Python


在PostgreSQL里,所有的存储函数需求都可以用PLPGSQL来实现。同时也支持用第三方语言来编写,这个就得看自己哪个方面熟练了。

不过要注意的一点是 PLPGSQL的效率怎么着都比其他第三方语言来的高效。

比如,简单的插入表的存储函数:

 

CREATE OR REPLACE FUNCTION ytt.insert_plpgsql(f_num integer)

RETURNS void

LANGUAGE plpgsql

AS $ytt$

declare i int := 0;

v_rank int := 0;

v_log_time timestamp;

begin

while i < f_num

loop

v_rank = ceil(random()*100);

v_log_time = now() - '1 day'::interval*ceil(random()*50);

insert into t1 (rank,log_time) values (v_rank,v_log_time);

i = i + 1;

end loop;

end;

$ytt$;

现在来插入100W条记录,花费时间大概为27秒。

t_girl=# select insert_plpgsql(1000000);

insert_plpgsql

----------------

(1 row)

Time: 27286.668 ms

我们改用python 来实现

在编写python 脚本前,确保系统已经载入了plpythonu扩展。

t_girl=# \dx plpythonu

List of installed extensions

Name    | Version |   Schema   |               Description

-----------+---------+------------+------------------------------------------

plpythonu | 1.0     | pg_catalog | PL/PythonU untrusted procedural language

(1 row)

以下是函数体:

CREATE OR REPLACE FUNCTION ytt.insert_py(f_num integer)

RETURNS void

LANGUAGE plpythonu

AS $ytt$

import datetime

import random

i = 0

while i < f_num:

v_rank = random.randrange(0,100)

v_log_time = datetime.datetime.now() - datetime.timedelta(days=random.randrange(0,50))

query0 = "insert into ytt.t1 (rank,log_time) values (" + str(v_rank) + ",'" + str(v_log_time)+ "')"

plpy.execute(query0)

i += 1

$ytt$;

清空表t1.

同样插入100W条记录, 这时候,时间上的差别显而易见了,用python 写的程序效率比数据库内部的语言慢了3倍。

t_girl=# select insert_py(1000000);

insert_py

-----------

(1 row)

Time: 86061.558 ms

那可以修改以上python 程序,让其效率来的高效一些,接近系统一些。 我们改用insert ... values ..()...() 的方式。

下面是函数体:

CREATE OR REPLACE FUNCTION ytt.insert_multi_py(f_num integer, f_values integer)

RETURNS text

LANGUAGE plpythonu

AS $ytt$

import datetime

import random

i = 0

j = 0

query0 = "insert into ytt.t1(rank,log_time) values "

data0 = ''

if (f_num/f_values)*f_values < f_num:

return 'Parameters should be times relation.(f_num:1000,f_values:10)'

else:

while i < int(f_num/f_values):

j = 0

while j < f_values:

v_rank = random.randrange(0,100)

v_log_time = datetime.datetime.now() - datetime.timedelta(days=random.randrange(0,50))

data0 = data0 + ",(" + str(v_rank) + ",'" + str(v_log_time)+ "')"

j += 1

result0 = query0 + data0[1:len(data0)]

plpy.execute(result0)

data0 = ''

i += 1

return 'Inserting ' + str(f_num) + ' rows'

$ytt$;

清空表t1.

继续插入100W条数据, 这时,插入时间和原始PLPGSQL的时间一致了。

t_girl=# select insert_multi_py(1000000,20);

insert_multi_py

------------------------

Inserting 1000000 rows

(1 row)

Time: 27587.715 ms

t_girl=#

 

©著作权归作者所有:来自51CTO博客作者david_yeung的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消