2013-05-24 19 views
15

Muszę okresowo zwiększać wartości w kolumnie z danymi, które otrzymuję w pliku. Tabela ma> 400000 wierszy. Jak dotąd wszystkie moje próby są bardzo słabe. Pisałem eksperyment, który odzwierciedla moje wymagania:Problemy z wydajnością aktualizacji zbiorczej 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())) 

czasy dostaję są takie:

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 

tak robi 400000+ ilość wierszy zajmie zbyt długo.

Jestem nowy sqlalchemy, ale zrobiłem dużo doc czytania, a ja po prostu nie mogę zrozumieć, co robię źle.

z góry dzięki!

Odpowiedz

13

Używasz poprawnego podejścia, wykonując zbiorczą aktualizację za pomocą pojedynczego zapytania.

Powodem dlaczego to trwa tak długo dlatego, że tabela nie ma indeks na sometable.column1. Ma tylko główny indeks w kolumnie id.

Zapytanie aktualizacja wykorzystuje sometable.column1 w którym klauzula zidentyfikować rekord. W związku z tym baza danych musi przeskanować wszystkie rekordy tabeli dla każdej aktualizacji pojedynczej kolumny.

Aby dokonać aktualizacji działał znacznie szybciej trzeba zaktualizować tabeli kodów definicji schematu dodać tworzenia indeksu definicji COLUMN1 z , index=True:

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

Testowałem zaktualizowany kod w moim komputerze - zajęło < 2 sekundy do uruchomienia programu.

Przyłącz się do opisu Twojego pytania - wpisujesz cały kod potrzebny do odtworzenia problemu.

+0

świetnie, dzięki! Słyszałem o indeksowaniu, ale myślałem, że to tylko wchodzi w grę z dużo większymi tomami. Wszystko jasne, okrzyki! – devboell