Массовое / пакетное обновление / обновление в PostgreSQL

Я пишу расширение Django-ORM, которое пытается кэшировать модели и откладывать сохранение модели до конца транзакции. Все почти готово, однако я столкнулся с неожиданной трудностью в синтаксисе SQL.

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

Теперь, насколько я могу судить, SQL на самом деле не предоставляет никаких операторов для выполнения пакетного обновления таблицы . Этот термин кажется сбивающим с толку , поэтому я объясню, что я имею в виду под этим. У меня есть массив произвольных данных, каждая запись описывает одну строку в таблице. Я хочу обновить определенные строки в таблице, каждая из которых использует данные из соответствующей записи в массиве. Идея очень похожа на пакетную вставку.

Например: Моя таблица может содержать два столбца «id» и «some_col» . Теперь массив, описывающий данные для пакетного обновления, состоит из трех записей (1, «первое обновление») , (2, «второе обновление») и (3 , 'третье обновление') . Перед обновлением таблица содержит строки: (1, «первая») , (2, «вторая») , (3, «третья») .

Я наткнулся на это сообщение:

Почему пакетные вставки / обновления выполняются быстрее? Как работают пакетные обновления?

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

Я также мог бы удалить все строки, которые требуют обновления, и повторно вставить их с помощью пакета insert, однако мне трудно поверить, что это действительно сработает лучше.

Я работаю с PostgreSQL 8.4, поэтому здесь также возможны некоторые хранимые процедуры. Однако, поскольку я планирую открыть исходный код проекта в конечном итоге, любые другие переносимые идеи или способы сделать то же самое в другой СУБД будут приветствоваться.

Последующий вопрос: Как сделать пакетную "вставку или-" Оператор update "/" upsert "?

Результаты теста

Я выполнил 100x раз 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 операторов на block, ~ 0,12 секунды .

Вывод: выполните как можно больше операций за одно соединение. execute (). Сам Django вызывает значительные накладные расходы.

Отказ от ответственности: я не вводил никаких индексов, кроме индексов первичного ключа по умолчанию, поэтому операции вставки могут выполняться быстрее из-за этого.

45
задан Community 23 May 2017 в 11:54
поделиться