2009-11-18 82 views
1

我有GUI將與postgres數據庫交互,使用psycopg2。我在多處理進程中有db連接,並通過多處理隊列發送SQL,並通過另一個隊列接收。python多處理db訪問非常慢

問題是速度非常慢。一個簡單的select *從一個小表(30行)可以是十分之一秒,或可以超過一秒鐘。

有沒有人有任何線索,爲什麼它如此緩慢?

新的信息:它的工作原理在WinXP,完全相同的代碼罰款,所以間歇延遲僅發生在我的Linux機器(Ubuntu的9.10)

更多信息:已經滅掉它看起來的選擇不是問題。

這是db類的主要部分。

class DataBase(multiprocessing.Process): 

    def __init__(self, conn_data, in_queue, out_queue): 
     multiprocessing.Process.__init__(self) 
     self.in_queue = in_queue 
     self.out_queue = out_queue 
     self.conn_data = conn_data 
     self.all_ok = True 

    def run(self): 
     proc_name = self.name 
     self.conn = self.get_connection(self.conn_data) 
     print("Running ", self.name) 
     while True: 
      next_job = self.in_queue.get() 
      print("Next Job: ",next_job) 
      if next_job is None: 
       # Stop Process 
       break 
      SQL = next_job[0] 
      callback = next_job[1] 
      result = self.execute(SQL) 
      self.out_queue.put((result, callback)) 
     print("Closing connection ", self.name) 
     self.conn.close() 
     return  

而在GUI我有這樣的:

def recieve_data(self): 
    "Revived data on the queue. Data is a tuple of the actual data and a calback name." 
    if self.recieve_queue.empty() == False: 
     data = self.recieve_queue.get() 
     callback_name = data[1] 
     try: 
      callback = getattr(self, callback_name) 
      callback(data[0]) 
     except AttributeError as e: 
      util.error_ui(err = e) 
     self.check_data_timeout = None 
     return False # Stop checking. 
    return True # Have the main loop keep checking for data. 

def request_data(self, SQL, callback): 
    self.send_queue.put((SQL, callback)) 
    self.check_data_timeout = gobject.timeout_add(50, self.recieve_data) # Poll the database recieved_queue 

回答

0

嘗試找出什麼是花時間 - 是它的多或數據庫?例如,嘗試直接從python交互式shell調用數據庫 - ipython shell有'time'和'timeit'命令來測量這樣的事情。或者,將DataBase.execute存根以返回罐頭值,並查看它所產生的差異。

那麼gobject.timeout_add呢?那是幹什麼的?延遲可能在那裏,而不是數據庫或多處理代碼。

+0

是的,我已經嘗試過。只需在一個進程中運行一個100選項,從shell使用「time python db_test.py」時需要大約0.3秒(包括python啓動時間) 當我今晚返回時,我將給出一些值(不包括linux在工作中) timeout_add在請求發送到數據庫後開始輪詢隊列,它是GUI主循環的一部分,允許用戶繼續與應用程序進行交互。 – Rob 2009-11-18 18:34:17

0

您是否嘗試過爲每個進程打開新的數據庫連接?在我看來,你只是增加開銷,試圖在不同的進程中重用它們。

此外,我不確定(你的示例是小的推斷),但它看起來像你打開每個查詢的新數據庫連接...你是否在每個查詢後關閉與self.conn.close()的連接?你應該有一個持久的聯繫。

+0

我爲每個進程打開一個新的連接,但在應用程序運行的整個過程中保持打開狀態。這允許不同的對象具有它們自己的單獨事務。 我會爲每個查詢創建一個新的遊標。 – Rob 2009-11-18 18:31:19

+0

嘗試在分析器下運行您的代碼。 – liori 2009-11-18 22:23:40

0

這似乎是問題或者具體到Ubuntu 9.10

所有工作正常,在Ubuntu 9.04和Win32,甚至在Win32託管在Ubuntu 9.10虛擬機上的錯誤。

感謝您的所有建議。