У меня есть две таблицы; один для хранения записей сгенерированных отчетов, а другой - для обновления флага, в котором были созданы отчеты. Этот сценарий будет запланирован, а 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
столбцы
ИМХО оба должны быть с той же скоростью, если использовать подготовленные заявления, обработка клиента незначительна. Почему бы вам просто не запустить некоторые тестовые примеры? – dnoeth
Спасибо, @dnoeth. Я буду запускать тестовые примеры. Я думал услышать предложения, основанные на здравой практике или теории. Я также использую подготовленные заявления. – paxmemento
1) Кажется, вы предполагаете, что случай 1 использует один запрос для вставки всех записей; что дело? (Кроме того, на ваш вопрос будет проще ответить на пример ваших данных, схемы базы данных и используемых вами запросов.) 2) Вы должны использовать заполнители в * each *, который использует значения переменных, независимо от того, работаете ли вы в петля или нет. – ThisSuitIsBlackNot