2014-01-03 3 views
2

У нас есть таблица из 9 столбцов и pk индексируется. у нас есть 169,3 миллиона записей, которые могут подняться до 250 миллионов. Каждый раз, когда я получаю обновление, мне приходится извлекать около 40 000 строк из базы данных для сравнения с использованием другого имени столбца с индексированным столбцом fk. после того, как я обрабатываю у меня есть:записи обновления на стол с миллионами записей

pk_update_nc = [pk1, pk2, pk5, .....pk40000] 
pk_update_PN = [pk3, pk4, pk6, .....pk35090] 
new_rows = [[row1], [row2], [row3], [row40000]] 

выше данных просто предложить:

таблицу обновлений и установить статус столбца = «NC», тип которого варьируется характер (3) где рк в таблице обновлений pk_update_nc и установить столбец статус = «ПН», тип которого варьируя характер (3) где рк в pk_update_PN

вставки строк в таблицу из new_rows

Что будет лучшим способом для обновления и вставки?

Method1:

start_transaction: 
for pk in pk_update_nc: 
    update table set status='NC' where table.pk = pk 
for pk in pk_update_PN: 
    update table set status='PN' where table.pk = pk 
for row in new_rows: 
    insert into table row = row 
commit 

Method2:

start_transaction; 
update table set status='NC' where table.pk in pk_update_nc; 
update table set status='PN' where table.pk in pk_update_PN; 
insert into table values rows 
commit 

method3:.

fill list of updated records list with rows instead of complete records, 
insert all records to table 
start_transaction: 
delete from table where fk = fk_provided; 
insert all rows, updated + new using \copy or django bulk create 
commit; 
  • Разъяснение по запросу для третьего способа * Это означает, извлечь строки из базы данных а nd локально, что является нормальным для каждого метода, теперь вместо вместо базы данных обновлений мы меняем старые записи, считая их новыми. удалите все записи из базы данных, имеющие fk, который является индексированным столбцом, , затем вставьте все записи как новые, используя \ copy. \ copy вставить записи магически быстро. для \ копирования визита postgresql COPY-TO/COPY-FROM

Method4? Предлагайте

FAQ:

Почему я должен тянуть 40000 строк из БД?

Это потому, что мы должны обработать эти записи против новых записей формы статуса старых & новых записей, старые строки передаются от многих использования случаев окончательных их статус. Это приводит к нескольким хитам для каждой строки и удару удара. поэтому я решил вытащить данные и процесс локально до окончательного обновления. Теперь мы хотим минимально возможного удара производительности для обновления db.

параллельность проблема:

Мы принимаем решение этого путем блокировки листов, подлежащая обработке. и следующий лист для одинаковые записи заблокированы для обработки до тех пор, пока не будет выполнена предыдущая задача . это ограничивает пользователей обработкой одного и того же листа fk как , обрабатываемых одновременно.Вопросы по базе данных могут быть: Должен ли я блокировать базу данных при обновлении и обработке, которая может занимать до 1-2 минут? база данных может быть заблокирована только для обновления, которая занимает меньше времени .

инструменты:

  • PSQL PostgreSQL 9,1 питона 2,7 Джанго 1,5
+1

Зачем вам нужно вытащить 40 000 строк по клиенту, почему вы не можете выполнить postgre для вас, это хорошо для такого рода вещей. –

+0

Не могли бы вы рассказать о методе 3? Из метода 1 и 2 я думаю, что метод 2 будет намного быстрее, потому что вы вызываете только одну команду SQL для каждой операции, а не по одной для каждой записи в каждой операции. – JustinHui

+0

@JustinHui Если Объяснение достаточно? – sharafjaffri

ответ

1

Вы пытаетесь положить помаду на свинью.

Это чрезвычайно неэффективно, чтобы извлекать 40 тыс. Строк, манипулировать ими в некоторых клиентских приложениях и записывать их обратно. Кроме того, вы легко сталкиваетесь с проблемами параллелизма в многопользовательской среде. Что делать, если что-то изменилось в базе данных, когда вы играли с данными в своем приложении? Как разрешать такие конфликты?

Правильный способ сделать это (если это вообще возможно) сделать это в базе данных с помощью операций на основе набора.

Data-modifying CTEs особенно полезны для более сложных операций, манипулирующих данными в нескольких таблицах. This search here on SO предлагает несколько примеров.

+0

Среди 40 тыс. Записей каждая запись сравнивается с его новыми записями. Это означает, что min 40k хитов для старых записей и 40k вставок. Это заканчивается мин. 80 000 обращений к высоконагруженному столу, рекомендуется ли это? Лучшей практикой может быть, но я должен заблокировать базу данных для поддержки параллелизма? Возможна ли эффективная и эффективная практика блокировки базы данных? – sharafjaffri

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