2012-11-06 29 views
0

使用csv_copy創建/填充表格時,我發現它有時非常緩慢。以下是核心代碼和一些示例輸出。創建和填充表格很慢並且不穩定

我有兩個問題:

  1. 我想不通爲什麼用於創建和填充表格的時間而變化。
  2. 我不確定是什麼導致「無」被打印。

代碼:

def create_populate_table(table_name,fields,types,cur): 
    sql = 'CREATE TABLE IF NOT EXISTS ' + table_name + ' (\n' 
    for i in xrange(len(fields)): 
     if i==0: 
      sql += fields[i]+' '+types[i]+' NOT NULL PRIMARY KEY,\n' 
     elif i==len(fields)-1: 
      sql += fields[i]+' '+types[i]+')' 
     else: 
      sql += fields[i]+' '+types[i]+',\n' 
    #print sql 
    cur.execute(sql) 
    conn.commit() 
    print "Table ",table_name," created ",timer() 

    cur.execute("SELECT count(*) from "+table_name) 
    if cur.fetchone()[0]>0: 
     return 
    # populate data into created table 
    fr= open(file, 'r') 
    fr.readline() 
    # parse and convert data into unicode 
    #data = unicode_csv_reader(fr, delimiter='|') 
    # anything can be used as a file if it has .read() and .readline() methods 
    data = StringIO.StringIO() 
    s=''.join(fr.readlines()) 
    while(s.find('\r\n')<>-1): 
     s=s.replace('\r\n','\n') 
    #timer() 
    while(s.find('||')<>-1 or s.find('|\n')<>-1): 
     s=s.replace('||','|0|') 
     s=s.replace('|\n','|0\n') 
    #timer() 
    #print s.split('\t')[:2] 
    #exit(0) 
    data.write(s) 
    data.seek(0) 
    try: 
     cur.copy_from(data, table_name,sep='|') 
     conn.commit() 
     print "Table ",table_name," populated ",timer() 
    except psycopg2.DatabaseError, e: 
     if conn: 
      conn.rollback() 
     print 'Error %s' % e  
    fr.close() 

輸出我看到:

ME_Features_20121001.txt表ME_Features_20121001創建1.44s 無表ME_Features_20121001填充1.48s無

FM_Features_20121001.txt表FM_Features_20121001創建67.92s 無表FM_Features_20121001 populat ED 0.22s無

NationalFile_20121001.txt(700MB)表NationalFile_20121001 創建9.34s無表NationalFile_20121001填充4963.18s 無

NJ_Features_20121001.txt表NJ_Features_20121001創建1.65s 無表NJ_Features_20121001填充41.11s無

PW_Features_20121001.txt表PW_Features_20121001創建1.73s 無表PW_Features_20121001填充0.20s無

+0

您是否必須使用自己的家庭成長的蟒蛇進口商?你可以使用Postgre的複製命令嗎? – Kuberchaun

+0

@JustBob上面的代碼*使用'COPY'命令。這就是'cur.copy_from'行的功能;它使用Psycopg2遊標運行'COPY ... FROM stdin'。 –

+0

如果您測量服務器端持續時間(請參閱PostgreSQL手冊,log_min_duration_statement,http://www.postgresql.org/docs/current/static/runtime-config-logging.html),它們是否與您的客戶看到的一致?一般來說,我希望所需的時間與CSV文件中的記錄數量及其磁盤大小大致成比例。這慢'CREATE TABLE'是一個跡象,你可能有緩慢的檢查點;看到http://wiki.postgresql.org/wiki/Logging_Checkpoints和http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server –

回答

1

timer()是如何定義的?我的盲猜(因爲你沒有提供它的代碼)是這個函數直接調用print來輸出測量的時間,但沒有明確返回任何東西 - 因此打印出None。如果目前還不清楚,看看下面的例子:

>>> def test(): 
...  print 'test' 
... 
>>> print 'This is a', test() 
This is a test 
None 

我不知道你的意思是說什麼的時間用於創建和填充表變化。填充表格所需的時間顯然取決於要插入的數據量。創建表格所需的時間在每種情況下應該大致相同,因此67.92s輸出的確看起來很可疑,但是......您確定它的測量是否正確?

再一次,我的猜測是timer()打印自上次調用以來的時間。也許你應該在開始你想測量的操作之前明確地重置它?我想那60秒是在撥打create_populate_table()之前花費的...

+0

感謝您的回答。我將檢查time()函數並回復給你。 – David