Postgresql單表【插入】/【更新】百萬數據

1、插入數據html

說到插入數據,一開始就想到:sql

insert int A values(*******************)bash

插入多條數據,最多想到:寫成這樣:dom

insert into A values(**********),(*************),(*****************)函數

可是在百萬數據面前,都太慢了。post

一、用腳本的方式性能

 1 #!/bin/bash
 2 strsql="insert into tbl_devaccess8021x (uidrecordid, dtaccesstime, strmac, strusername, strswitchip, strifname, iisauthsuc,iisantipolicy,iisaccessed,strmachinecode,strrandomcode,iaccesstype,straccessfailedcode,uidroleid ,struserdes) values('d71803axxx1','2019-08-02 20:37:35', '1:2:3:4:5:6', 'criss0', '192.168.2.146','FastEthernet0/1',0,0,1,'000000000020A0B01','020A0B01',1,0,'研發','crissxu10')"
 3 
 4 for ((i=1; i <=3000000; i++))
 5 do
 6     strsql=$strsql",('d71803axxx$i',$(date +%s), '1:2:3:4:5:$i', 'criss$i', '192.168.2.$i','FastEthernet0/1',0,0,1,'000000000020A0B01','020A0B01',1,0,'研發','crissxu10')"
 7 
 8 done
 9 echo $strsql
10 #psql -d xxx -U xxx -c "$strsql"

上述在數據量小的時候,能夠採用,數據量大的話特別耗時。優化

二、postgresql提供了copy函數,方便批量導入數據。ui

copy_from的參數說明:copy_from(filetablesep='\t'null='\\N'size=8192columns=None)spa

 1 import sys
 2 import psycopg2
 3 if sys.version_info.major == 2:
 4     import StringIO as io
 5 else:
 6     import io
 7 from datetime import datetime
 8 if __name__=='__main__':
 9     s = ""
10     start_time = datetime.now()
11     for i in range(0,10):
12         str_i = str(i)
13         temp = "d71803axxx{0}\t{1}\t1:2:3:4:5:{2}\tcriss{3}\t192.168.2.{4}\tFastEthernet0/1\t0\t0\t1\t000000000020A0B01\t020A0B01\t1\t0\t研發\tcrissxu10\n".format(str_i, datetime.now(),str_i,str_i,str_i)
14         s +=temp
15     conn = psycopg2.connect(host='127.0.0.1',user="xxx",password="xxx",database="xxx")
16     cur = conn.cursor()
17     cur.copy_from(io.StringIO(s),'tbl_devaccess8021x',columns=('uidrecordid', 'dtaccesstime', 'strmac', 'strusername', 'strswitchip', 'strifname', 'iisauthsuc','iisantipolicy','iisaccessed','strmachinecode','strrandomcode','iaccesstype','straccessfailedcode','uidroleid' ,'struserdes'))
18     conn.commit()
19     cur.close()
20     conn.close()
21     end_time = datetime.now()
22     print ('done. time:{0}'.format(end_time - start_time))

用copy_from 函數執行三百萬的數據,時間大概7分鐘左右。

三、先往臨時表中插入,而後再同步

1 insert into source_table select  temporary_table

 

 

2、更新數據

update table set col = value where col_condition=value;

更新數據的步驟是先找到符合條件的col_condition的數據,而後再執行更新。少許數據的時候,查詢速度快,當表裏的數據達到必定量的時候,查詢性能受到影響,從而致使更新效率下降。

解決辦法:

一、對查詢條件加索引。

二、將多條數據合併成一條sql語句

1 update target_table set c2 = t.c2 from (values(1,1),(2,2),(3,3),…(2000,2000)) as t(c1,c2) where target_table.c1=t.c1

 

 

Reference:

【1】 http://www.voidcn.com/article/p-stwpqgta-bdq.html

 

"後來看到葛班長的日誌,他經過Python在SQLite中插入100萬條數據只用了4秒,緣由在於Python對全部的這100萬條插入語句進行了優化,將全部的插入操做放到了同一個事務中,這樣極大的減小了開啓和取消事務的時間,而正是這部分操做會消耗大量的時間"

這應該能夠解釋爲何方法2

【2】http://www.voidcn.com/article/p-vvuwvbyw-yu.html

【3】https://help.aliyun.com/knowledge_detail/59076.html

相關文章
相關標籤/搜索