postgres 使用存储过程批量插入数据的操作
参考官方文档
createorreplacefunctioncreatData2()returns booleanAS $BODY$ declareiiinteger; begin II:=1; FORiiIN1..10000000LOOP INSERTINTOipm_model_history_data(res_model,res_id)VALUES(116,ii); endloop; returntrue; end; $BODY$ LANGUAGEplpgsql; select*fromcreatData2()astab;
插入1千万条数据耗时610s,当然字段不多的情况下。
补充:Postgresql存储过程--更新或者插入数据
要记录某一时段机器CPU、内存、硬盘的信息,展示的时间粒度为分钟,但是为了精确,输入数据源的时间粒度为6s。这个统计过程可以在应用层做好,每分钟插入一次,也可以在数据库层写个存储过程来完成,根据传入数据的时间来判断是更新数据库旧数据还是插入新数据。
同时,这些数据只需要保留一周,更老的数据需要被删除。删除动作可以每天定时执行一次,也可以写在存储过程中每次检查一下。
考虑到性能在此时没什么太大约束,而后面存储过程的接口方式更漂亮些,不用应用层去关心数据到底组织成什么样,因此实现了一个如下:
PostgresqlV8.3 CREATEORREPLACEFUNCTIONinsert_host_status(_log_datetimestampwithouttimezone,_hostinet,_cpuinteger,_meminteger,_diskinteger) RETURNSvoidAS $BODY$ DECLARE new_starttimestampwithouttimezone; current_starttimestampwithouttimezone; c_idinteger; c_log_datetimestampwithouttimezone; c_cpuinteger; c_meminteger; c_diskinteger; c_countinteger; date_spaninterval; BEGIN --insertorupdate SELECTid,log_date,cpu,mem,disk,countINTOc_id,c_log_date,c_cpu,c_mem,c_disk,c_countFROMhost_status_byminuteWHEREhost=_hostORDERBYidDESClimit1; SELECTtimestamp_mi(_log_date,c_log_date)INTOdate_span; IFdate_span>='00:00:60'ORc_idISNULLTHEN INSERTINTOhost_status_byminute(log_date,host,cpu,mem,disk,count)values(_log_date,_host,_cpu,_mem,_disk,1); ELSIFdate_span>='-00:00:60'THEN c_mem:=((c_mem*c_count)+_mem)/(c_count+1); c_cpu:=((c_cpu*c_count)+_cpu)/(c_count+1); c_disk:=((c_disk*c_count)+_disk)/(c_count+1); c_count:=c_count+1; UPDATEhost_status_byminuteSETmem=c_mem,cpu=c_cpu,disk=c_disk,count=c_countWHEREid=c_id; ENDIF; --deleteolddata SELECTdate_mii(date(now()),6)INTOnew_start; SELECTdate(log_date)fromhost_status_byminutelimit1INTOcurrent_start;--omitabughappenedwhendateisdisordered. IFnew_start>current_startTHEN DELETEFROMhost_status_byminutewherelog_date以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。