2016-05-28 6 views
3

Я пытаюсь сделать крупномасштабную вставку в базу данных sqlite с peewee. Я использую atomic, но производительность все еще ужасна. Я вставляю строки в блоках из 2500 строк, и из-за SQL_MAX_VARIABLE_NUMBER я вставляю около 200 из них за раз. Вот код:peewee с объемной вставкой очень медленно в sqlite db

with helper.db.atomic(): 
    for i in range(0,len(expression_samples),step): 
     gtd.GeneExpressionRead.insert_many(expression_samples[i:i+step]).execute() 

И список expression_samples приведен список словарей с соответствующими полями для GeneExpressionRead модели. Я приурочил этот цикл, и для его выполнения требуется от 2 до 8 секунд. У меня есть миллионы строк для вставки, и способ, которым мой код написан сейчас, скорее всего, займет 2 дня. Согласно this post, есть несколько прагм, которые я установил, чтобы улучшить производительность. Это также ничего не меняет для меня, как результат. Наконец, в соответствии с this test on the peewee github page должно быть возможно очень быстро вставить много строк (~ 50 000 за 0.3364 секунды), но также кажется, что автор использовал исходный код sql для получения этой производительности. Кто-нибудь мог сделать такую ​​высокоэффективную вставку, используя методы peewee?

Редактировать: Не понял, что тест на странице github peewee был для MySQL вставок. Может или не может применяться к этой ситуации.

ответ

5

Mobius пытался помочь в комментариях, но там много дезинформации.

  • Peewee создает индексы для внешних ключей при создании таблицы. Это происходит для всех поддерживаемых в настоящее время СУБД.
  • Включение внешнего ключа PRAGMA замедляет работу, почему бы и нет?
  • Для обеспечения максимальной производительности не создавайте индексов на таблице, в которую вы загружаете объемную загрузку. Загрузите данные, , затем создайте индексы. Это намного меньше работает для базы данных.
  • Как вы отметили, отключение автоматического приращения для объемной загрузки ускоряет работу.

Другая информация:

  • Использование ПРАГМА journal_mode = валь;
  • Использовать PRAGMA synchronous = 0;
  • Использовать PRAGMA locking_mode = EXCLUSIVE;

Это хорошие настройки для загрузки в кучу данных. Проверьте SQLITE документы для получения дополнительной информации:

http://sqlite.org/pragma.html

+1

Да, после долгих поисков это в значительной степени то, что я сделал. Спасибо за помощь! – themantalope

-1

Во всей документации, где код с использованием atomic отображается как менеджер контекста, он используется как функция. Так как кажется, что вы никогда не видите свой код exit блок with, вы, вероятно, не видите ошибку о том, что у вас нет метода __exit__.

Вы можете попробовать with helper.db.atomic():?

atomic() начинает транзакцию. Без открытой транзакции вставки намного медленнее, потому что для каждой записи нужно делать несколько дорогих книг, а не только в начале и конце.

EDIT

Поскольку код, чтобы начать этот вопрос был изменен, я могу иметь больше информации о таблице вы вставляете в? Является ли это большим, сколько индексов есть?

Поскольку это SQLite, вы просто пишете файл, но знаете ли вы, что этот файл находится на локальном диске или на сетевом диске? У меня были проблемы, подобные этому, потому что я пытался вставить в базу данных в NFS.

+0

не уверен, что вы имеете в виду 'с helper.db.atomic():'. Это то, что у меня есть в моем коде и было указано в вопросе. – themantalope

+0

О, я вижу это сейчас. Недопустимая '()' была опечаткой. Фиксация сейчас. – themantalope

+0

См. Мой отредактированный контент. Теперь, когда потенциально тривиальный исключается, мне нужно больше узнать о вашей схеме базы данных. Вы создаете базу данных для данных RNA-seq? GeneExpressionRead звучит как запись FastQ или SAM. – mobiusklein

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