2017-03-10 6 views
1

저는 파이썬을 사용하여 Postgres 데이터베이스에서 데이터를 가져 왔습니다. 그리고 그것은 많은 기억을 차지하고 있습니다.Postgres 데이터베이스에서 데이터를 가져 오는 동안 과도한 메모리 사용

memory usage

다음 함수는 내가 실행하고있는 유일한 기능이며, 메모리를 너무 많이 차지 :로 아래 볼 수 있습니다. 나는 fetchmany()을 사용하고 작은 덩어리로 데이터를 가져 왔습니다. 나는 또한 cur 커서를 반복적으로 사용하려고 시도했다. 그러나 이러한 모든 방법은 결국 과도한 양의 메모리 사용으로 끝납니다. 왜 이런 일이 일어나는 지 아무 단서가 있습니까? 이 문제를 완화하는 데 도움이 될 수있는 Postgres 끝에서 조정해야 할 사항이 있습니까?

def checkMultipleLine(dbName): 
    ''' 
    Checks for rows that contain data spanning multiple lines 

    This is the most basic of checks. If a aprticular row has 
    data that spans multiple lines, then that particular row 
    is corrupt. For dealing with these rows we must first find 
    out whether there are places in the database that contains 
    data that spans multiple lines. 
    ''' 

    logger = logging.getLogger('mindLinc.checkSchema.checkMultipleLines') 
    logger.info('Finding rows that span multiple lines') 

    schema = findTables(dbName) 

    results = [] 
    for t in tqdm(sorted(schema.keys())): 

     conn = psycopg2.connect("dbname='%s' user='postgres' host='localhost'"%dbName) 
     cur = conn.cursor() 
     cur.execute('select * from %s'%t) 
     n = 0 
     N = 0 
     while True: 
      css = cur.fetchmany(1000) 
      if css == []: break 
      for cs in css: 
       N += 1 
       if any(['\n' in c for c in cs if type(c)==str]): 
        n += 1 
     cur.close() 
     conn.close() 

     tqdm.write('[%40s] -> [%5d][%10d][%.4e]'%(t, n, N, n/(N+1.0))) 
     results.append({ 
      'tableName': t, 
      'totalRows': N, 
      'badRows' : n, 
     }) 


    logger.info('Finished checking for multiple lines') 

    results = pd.DataFrame(results)[['tableName', 'badRows', 'totalRows']] 
    print results 
    results.to_csv('error_MultipleLine[%s].csv'%(dbName), index=False) 

    return results 
+0

어떻게 하나 이상의 파이썬 프로세스를 가져 왔습니까? psycopg2가 그렇게합니까? – hurturk

+0

나는 그 일을 psycopy라고 생각하고 있습니다. 나는 새로운 프로세스를 시작하기 위해 특별한 코드를 작성하지 않았다 ... – ssm

+0

나는 [대답] (http://stackoverflow.com/a/28343332/1233686)에 따라 버퍼를 제한하는 옵션을 발견했다. 너 이거 봤어? – hurturk

답변

2

Psycopg2이 answer에 명시된 server-side cursors 큰 쿼리에 사용되는 지원합니다. 클라이언트 쪽 버퍼 설정과 함께 사용하는 방법은 다음과 같습니다.

cur = conn.cursor('cursor-name') 
cur.itersize = 10000 # records to buffer on a client 

이렇게하면 메모리 사용량이 줄어들 수 있습니다.