2016-09-30 56 views
2

我正在編寫一個程序來將數據加載到特定的數據庫中。這是我在做什麼現在...postgres INSERT命令中的速度改進

 conn = psycopg2.connect("dbname='%s' user='postgres' host='localhost'"%dbName) 
     cur = conn.cursor() 

     lRows = len(rows) 
     i, iN = 0, 1000 
     while True: 

      if iN >= lRows: 
       # write the last of the data, and break ... 
       iN = lRows 
       values = [dict(zip(header, r)) for r in rows[i:iN]] 
       cur.executemany(insertString, values) 
       conn.commit() 
       break 

      values = [dict(zip(header, r)) for r in rows[i:iN]] 
      cur.executemany(insertString, values) 
      conn.commit() 

      i += 1000 
      iN += 1000 

     cur.close() 
     conn.close() 

我知道關於關於使用COPY命令this問題。但是,在我可以將文件上傳到數據庫之前,我需要對我的文件進行一些簿記。因此我以這種方式使用Python。

我有一對夫婦在如何使事情更快的問題...

  1. 它會更好(或可能)做許多cur.executemany()語句並在最後一個conn.commit()?這意味着我將在cur.close()聲明之前放置一個單個conn.commit()聲明。
  2. 我總是看到其他人使用cur.executemany()批量的1000個左右的記錄。這是通常的情況還是僅僅對我從文件中讀取的整個記錄​​集執行cur.executemany()是可能的。我可能會有數十萬條記錄,或者可能有一百多萬條記錄。 (我有足夠的RAM來適應內存中的整個文件)。我怎麼知道我可以在任何時候上傳的記錄數量的上限。
  3. 我正在爲每個打開的文件重新建立數據庫連接。我這樣做是因爲,這個過程花了我很多天才能完成,並且我不希望連接問題會破壞整個數據,如果連接在任何時候丟失的話。我有超過一千個我需要經歷的文件。我們正在建立的這千個連接將成爲該流程所用時間的重要組成部分嗎?
  4. 我在程序中還有其他的事情,我不應該這樣做可以縮短整個過程的時間?

非常感謝任何幫助,我可以得到。對不起,這些問題很基本。我剛剛開始使用Python的數據庫,出於某種原因,我現在似乎沒有任何明確的答案。

回答

1
  1. 正如你在第3頁提到你擔心數據庫連接,這可能會破壞,所以如果你只是所有插入後使用一個conn.commit(),你可以很容易鬆動已經插入,但如果你的連接不COMMITED數據在conn.commit()之前休息。如果你在cur.executemany()之後做conn.commit(),那麼你不會失去一切,只有最後一批。所以,這取決於您需要支持的工作流程。

  2. 每個批次的記錄數是插入速度和其他事物之間的折衷。您需要選擇滿足您需求的值,您可以使用每批1000個記錄測試腳本,每批10000個,並檢查差異。 在一個cur.executemany()中插入整個文件的情況具有原子性的優點:如果它已經被執行,那意味着來自這個特定文件的所有記錄都被插入了,所以我們回到p。 1.

  3. 我認爲在您的案例中建立新連接的成本並不重要。比方說,如果需要一秒建立新的連接,1000個文件將在1000天內連接花費在連接上。

  4. 程序本身看起來不錯,但我還是建議你採取COPY TO命令的外觀與UNLOGGEDTEMPORARY表,但它真的會加快您的進口。