Я пишу расширение Django-ORM, которое пытается кэшировать модели и откладывает сохранение моделей до конца транзакции.Это почти все сделано, однако я столкнулся с неожиданной трудностью в синтаксисе SQL.
Я не большой администратор баз данных, но, насколько я понимаю, базы данных не очень эффективно работают для многих небольших запросов.Несколько больших запросов намного лучше.Например, лучше использовать большие пакетные вставки (скажем, 100 строк одновременно) вместо 100 однострочных.
Теперь, насколько я вижу, SQL на самом деле не предоставляет никаких операторов для выполнения пакетного обновления.на столе.Термин, кажется, сбивает с толку , поэтому я объясню, что я имею в виду под этим.У меня есть массив произвольных данных, каждая запись описывает одну строку в таблице.Я хотел бы обновить определенные строки в таблице, каждая из которых использует данные из соответствующей записи в массиве.Идея очень похожа на пакетную вставку.
Например: моя таблица может иметь два столбца "id"
и "some_col"
.Теперь массив, описывающий данные для пакетного обновления, состоит из трех записей (1, 'first updated')
, (2, 'second updated')
и (3, 'third updated')
.Перед обновлением таблица содержит строки: (1, 'first')
, (2, 'second')
, (3, 'third')
.
Я наткнулся на это сообщение:
Почему пакетные вставки / обновления быстрее?Как работают пакетные обновления?
, который, кажется, делает то, что я хочу, однако я не могу понять синтаксис в конце.
Я также мог бы удалить все строкикоторые требуют обновления и переустановки их с помощью пакетной вставки, однако мне трудно поверить, что это на самом деле будет работать лучше.
Я работаю с PostgreSQL 8.4, поэтому здесь также возможны некоторые хранимые процедуры.Однако, поскольку я планирую в конечном итоге открыть исходный код проекта, любые более переносимые идеи или способы сделать то же самое в другой СУБД приветствуются.
Последующий вопрос: Как сделатьпакетный оператор «вставка или обновление» / «upsert»?
результаты теста
Я выполнил 100 раз 10 операций вставки, распределенных по 4 различным таблицам (так1000 вкладок в общей сложности).Я тестировал на Django 1.3 с бэкэндом PostgreSQL 8.4.
Вот результаты:
- Все операции, выполняемые через Django ORM - каждый проход ~ 2,45 секунды ,
- Те же операции, но без Django ORM - каждый проход ~ 1,48 секунды ,
- Только операции вставки, без запроса базы данных для значений последовательности ~ 0,72секунд ,
- Только операции вставки, выполненные в блоках по 10 (всего 100 блоков) ~ 0,19 секунд ,
- Только операции вставки, один большой блок выполнения ~ 0,13 секунды .
- Только операции вставки, около 250 операторов на блок, ~ 0,12 секунды .
Вывод: выполнить столько, сколькооперации, насколько это возможно в одном подключении. execute ().Сам Django вносит существенные издержки.
Отказ от ответственности: я не представил никаких индексов, кроме индексов первичного ключа по умолчанию, поэтому операции вставки могут выполняться быстрее из-за этого.