2009-11-18 4 views
1

psycopg2를 사용하여 postgres 데이터베이스와 상호 작용할 GUI가 있습니다. 다중 처리 프로세스에서 db 연결을 사용하고 다중 처리 대기열을 통해 SQL을 보내고 다른 대기열을 통해 수신합니다.파이썬 멀티 프로세싱 db 액세스가 매우 느림

문제는 속도가 매우 느립니다. 작은 테이블 (30 개 행)의 간단한 select *는 1/10th 초 또는 1 초 이상 걸릴 수 있습니다.

왜 그렇게 느린 지에 대한 단서가 있습니까?

새로운 정보 : 그것은 WINXP, 동일한 코드에 잘 작동하므로 간헐적 인 지연은 단지 내 리눅스 박스에 무슨 일이 일어나고 (우분투 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

시도를 - 그것은 다중 또는 데이터베이스입니다? 예를 들어, 파이썬 대화 형 쉘에서 데이터베이스를 직접 호출 해보십시오. ipython 쉘은 이와 같은 것을 측정하기위한 'time'및 'timeit'명령을 가지고 있습니다. 또는 DataBase.execute를 스텁하여 준비된 값을 반환하고 어떤 차이가 있는지 확인하십시오.

gobject.timeout_add는 어떤가요? 그게 뭐예요? 지연이 데이터베이스 또는 다중 처리 코드가 아닌 그곳에있을 수 있습니다.

+0

예, 시도했습니다. 하나의 프로세스에서 100 개의 셀렉트를 실행하는 것은 "python db_test.py"를 사용하여 쉘에서 시간 (python 시작 시간 포함)을 약 0.3 초 ​​걸립니다. 오늘 밤에 반환 할 때 통조림 값을 줄 것입니다 상자 작업시) timeout_add는 요청이 db로 보내지면 대기열을 폴링하기 시작합니다. 사용자가 응용 프로그램과 상호 작용할 수있게 해주는 GUI 기본 루프의 일부입니다. – Rob

0

각 프로세스에 대해 새 데이터베이스 연결을 열어 보았습니까? 다른 프로세스에서 재사용을 위해 단순히 오버 헤드를 추가하는 것처럼 보입니다.

또한, (귀하의 견본은 작게는 추측합니다.)하지만 각 검색어에 대해 새 DB 연결을 여는 것처럼 보입니다 ... 각 검색어를 입력 한 후 self.conn.close()과의 연결을 종료 하시겠습니까? 오래 지속되는 연결이 있어야합니다.

+0

각 프로세스마다 새 연결을 열지 만 앱이 실행되는 동안 열어 둡니다. 이렇게하면 서로 다른 객체가 고유 한 개별 트랜잭션을 가질 수 있습니다. 각 쿼리에 대해 새 커서를 만듭니다. – Rob

+0

프로파일 러에서 코드를 실행 해보십시오. – liori

0

문제 나 우분투 9.10

모든 우분투 9.10에서 호스팅되는 가상 머신에, 심지어는 Win32에, 우분투 9.04 및 Win32에서 잘 작동과 관련된 버그 것 같다.

모든 조언을 제공해 주셔서 감사합니다.