2015-05-11 5 views
2

У меня есть две таблицы; один для хранения записей сгенерированных отчетов, а другой - для обновления флага, в котором были созданы отчеты. Этот сценарий будет запланирован, а SQL-версии будут реализованы. Тем не менее, существует две реализации сценария:Пакетная обработка по сравнению с транзакциями с одной строкой для атомарности

Случай 1:

- Insert all the records, then 
- Update all the flags, 
- Commit if all is well 

Случай 2:

While (there are records) 
- Insert a record, 
- Update the flag 
- Commit if all is well 

Какой должна быть предпочтительным и почему?

Сделка для случая 1 предназначена для всех вставок, затем все обновления. Это все или ничего. Я считаю, что это быстрее, или нет, если соединение с удаленной базой данных прерывается. Это требует очень небольшой обработки клиентской стороны. Но если вставки не пройдут на полпути, нам придется переходить с вершины.

Сделка для случая 2 - одна вставка, обновление. Это требует отслеживания вставленных записей и обновления конкретных записей. Мне придется использовать заполнители, и, хотя предоставленная база данных может кэшировать SQL, и использовать план выполнения запросов несколько раз, я подозреваю, что это будет медленнее, чем Case 1 из-за дополнительной обработки на стороне клиента. Однако по ненадежной связи, которую мы можем предположить, это выглядит лучше.

EDIT 5/11/2015 11:31 утра

СЛУЧАЙ 1 сниппет:

my $sql = "INSERT INTO eval_rep_track_dup\@prod \ 
      select ert.* \ 
      from eval_rep_track ert \ 
      inner join \ 
      (
        select erd.evaluation_fk, erd.report_type, LTRIM(erd.assign_group_id, '/site/') course_name \ 
        from eval_report_dup\@prod erd \ 
        inner join eval_report er \ 
        on er.id = erd.id \ 
        where erd.status='queue' \ 
        and er.status='done' \ 
      ) cat \ 
      on ert.eval_id = cat.evaluation_fk \ 
      and ert.report_type = cat.report_type \ 
      and ert.course_name = cat.course_name"; 
    my $sth = $dbh->prepare($sql) or die "Error with sql statement : $DBI::errstr\n"; 
    my $noterror = $sth->execute() or die "Error in sql statement : " . $sth->errstr . "\n"; 

...

# update the status from queue to done  
     $sql = "UPDATE eval_report_dup\@prod \ 
       SET status='done' \ 
       WHERE id IN \ 
       (\ 
         select erd.id \ 
         from eval_report_dup\@prod erd \ 
         inner join eval_report er \ 
         on er.id = erd.id \ 
         where erd.status='queue' \ 
         and er.status='done' \ 
       )"; 

     $sth = $dbh->prepare($sql); 
     $sth->execute(); 

eval_rep_track_dup имеет 3 number, 8 varchar2 и через timestamp колонны eval_report_dup имеет 10 number, 8 varchar2 и 3 timestamp столбцы

+0

ИМХО оба должны быть с той же скоростью, если использовать подготовленные заявления, обработка клиента незначительна. Почему бы вам просто не запустить некоторые тестовые примеры? – dnoeth

+0

Спасибо, @dnoeth. Я буду запускать тестовые примеры. Я думал услышать предложения, основанные на здравой практике или теории. Я также использую подготовленные заявления. – paxmemento

+0

1) Кажется, вы предполагаете, что случай 1 использует один запрос для вставки всех записей; что дело? (Кроме того, на ваш вопрос будет проще ответить на пример ваших данных, схемы базы данных и используемых вами запросов.) 2) Вы должны использовать заполнители в * each *, который использует значения переменных, независимо от того, работаете ли вы в петля или нет. – ThisSuitIsBlackNot

ответ

0

Hi Хорошо, если бы это было до меня, я бы сделал последний метод. Основная причина заключалась бы в том, что сервер/программа снизилась в середине обработки; вы можете легко перезапустить работу. Успехов р^

+0

Спасибо @joe_evans. Я тоже подумал об этом после реализации Case 1. – paxmemento