用第三方語言編寫PostgreSQL 存儲函數

在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=# 


發佈了97 篇原創文章 · 獲贊 2 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章