2013-05-24 1 views
15

파일에서받은 데이터로 주기적으로 값을 증가시켜야합니다. 테이블에> 400000 개의 행이 있습니다. 지금까지 모든 시도는 성능이 매우 떨어졌습니다. 내 요구 사항을 반영하는 실험을 작성했습니다 :sqlalchemy 대량 업데이트 성능 문제

#create table 
engine = create_engine('sqlite:///bulk_update.db', echo=False) 
metadata = MetaData() 

sometable = Table('sometable', metadata, 
    Column('id', Integer, Sequence('sometable_id_seq'), primary_key=True), 
    Column('column1', Integer), 
    Column('column2', Integer), 
) 

sometable.create(engine, checkfirst=True) 

#initial population 
conn = engine.connect() 
nr_of_rows = 50000 
insert_data = [ { 'column1': i, 'column2' : 0 } for i in range(1, nr_of_rows)] 
result = conn.execute(sometable.insert(), insert_data) 

#update 
update_data = [ {'col1' : i, '_increment': randint(1, 500)} for i in range(1, nr_of_rows)] 

print "nr_of_rows", nr_of_rows 
print "start time : " + str(datetime.time(datetime.now())) 

stmt = sometable.update().\ 
     where(sometable.c.column1 == bindparam('col1')).\ 
     values({sometable.c.column2 : sometable.c.column2 +  bindparam('_increment')}) 

conn.execute(stmt, update_data) 

print "end time : " + str(datetime.time(datetime.now())) 

내가 할 시간이 있습니다

nr_of_rows 10000 
start time : 10:29:01.753938 
end time : 10:29:16.247651 

nr_of_rows 50000 
start time : 10:30:35.236852 
end time : 10:36:39.070423 

그렇게 행 400000+ 양이 너무 오래 걸릴 일을.

저는 sqlalchemy를 처음 사용 합니다만, 나는 많은 독서를했으며, 내가 잘못하고있는 것을 이해하지 못했습니다.

미리 감사드립니다.

답변

13

단일 쿼리로 대량 업데이트를 수행하면 올바른 방법을 사용하고 있습니다.

테이블이 sometable.column1에 색인이 없기 때문에 오래 걸리는 이유가 있습니다. 열 id에 대한 기본 색인 만 있습니다.

업데이트 쿼리는 레코드를 식별하기 위해 where 절에 sometable.column1을 사용합니다. 따라서 데이터베이스는 모든 단일 열 업데이트에 대해 모든 테이블 레코드를 스캔해야합니다.

가 갱신 실행 훨씬 빠르게 당신이 , index=True로, 컬럼 정의에 인덱스 생성을 추가 할 테이블 스키마 정의 코드를 업데이트해야하려면 :

sometable = Table('sometable', metadata, 
    Column('id', Integer, Sequence('sometable_id_seq'), primary_key=True), 
    Column('column1', Integer, index=True), 
    Column('column2', Integer), 
) 

을 내 컴퓨터에 업데이트 된 코드로 테스트 - 그것은 < 2 초 걸렸다 프로그램을 실행할 수 있습니다.

BTW 귀하의 질문에 대한 명언 - 문제를 재현하는 데 필요한 모든 코드를 기재하십시오.

+0

대단히 감사합니다. 색인 생성에 대해 들어 봤지만 훨씬 많은 양으로 재생할 수 있다고 생각했습니다. 이제 모든 것이 명확 해집니다. – devboell