2013-05-24 4 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.

В запросе на обновление используется sometable.column1 в предложении where, чтобы идентифицировать запись. Таким образом, база данных должна проверять все записи таблицы для каждого обновления столбца.

Чтобы сделать обновление работать намного быстрее, вам нужно обновить код определения схемы таблицы, чтобы добавить создание индекса для определения 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 kudos на ваше описание вопроса - вы помещаете весь код, необходимый для воспроизведения вашей проблемы.

+0

отлично, спасибо! Я слышал об индексировании, но я думал, что это только вступает в игру с гораздо большими объемами. Теперь все ясно, ура! – devboell