2015-03-15 3 views
0

У меня есть 12000 элементов в таблице, и я хочу обновлять и совершать каждый элемент по отдельности.Ускорить обновление элементов отдельно

items = db.session.query(User).all() 

for item in items: 
    item.active = 0 
    # do stuff 
    db.session.commit() 

Мне нужно совершить каждую итерацию, чтобы изменения немедленно попадали в базу данных. Если я выбираю все строки в моем первом запросе, фиксация выполняется медленно. Если я выбираю меньший набор данных (например, 400 строк), это быстро.

Что делать для повышения производительности без выбора меньшего набора данных?

+0

* «Мне нужно совершить на каждой итерации, поэтому изменения немедленно переходят в базу данных». * - почему? Если вы совершаете после каждого обновления, вы не используете базу данных так, как она предназначена для использования, это всегда будет медленным. –

+0

Почему-то я начинаю «задавать» каждую ночь, чтобы обнаружить - может ли пользователь войти на сайт или нет. Поэтому я получаю всех пользователей и начинаю это обнаруживать. И я хочу как можно скорее отправить эту дату в базу данных в базу данных. – zt50tz

+0

Это звучит как ужасный подход к контролю доступа по нескольким причинам. Но кроме того, вопрос в том, что «достаточно быстро» в этом контексте. И независимо от того, требуется ли 5 ​​или 20 секунд для деактивации пользователя, не имеет значения, будете ли вы проверять один раз в день в любом случае. «КОМИТЕТ» на несколько величин дороже, чем ваш «ОБНОВЛЕНИЕ», вы излишне затягиваете этот процесс следующим образом (* и * вы полностью нарушаете [транзакцию] (http://en.wikipedia.org/wiki/Database_transaction) как побочный эффект). –

ответ

1

SQLAlchemy кэширует все запрошенные элементы внутри, но заканчивает этот кеш при выдаче commit. Таким образом, экземпляр, доступный на следующей итерации, находится в состоянии «expired», а SQLAlchemy повторно запрашивает базу данных. Таким образом, вы эффективно делать:

  1. массивный запрос в начале для 12000 пунктов
  2. 12000 совершает
  3. 11999 запросов для отдельных элементов
  4. 24000 запросов всего

разница, которую вы видите, когда вы выбираете 400 только в первый раз, - это просто эффект масштаба: вы просматриваете только одну треть из числа циклов select/commit.

Существует не документированный способ предотвращения использования механизма истечения срока действия. Вы можете смириться с выполнением 24000 запросов, или вы можете совершить один раз в конце.

Вам, скорее всего, будет лучше, если вы совершите только один цикл после одной транзакции.

Смежные вопросы