Вопрос
Используя Oracle 10g, доступ к которому осуществляется через Perl DBI, у меня есть таблица с несколькими десятками миллионов строк, обновляемая несколько раз в секунду, при этом считываемая гораздо чаще из другого процесса.
Вскоре частота обновлений увеличится на порядок (может быть, на два).Кто-то предположил, что фиксация каждых N обновлений, а не после каждого обновления, повысит производительность.
У меня есть несколько вопросов:
- Будет ли это быстрее или медленнее, или это зависит (планирую провести тест в обоих направлениях, как только смогу получить достойную симуляцию новой нагрузки)
- Почему это поможет / помешает производительности?
- Если "это зависит ..." , то от чего ?
- Если это поможет, каково наилучшее значение N?
- Почему у моего местного администратора базы данных не может быть полезного прямого ответа, когда он мне нужен?
(На самом деле я знаю ответ на этот вопрос) :-)
Редактировать:
@codeslave :Спасибо, кстати, потеря незафиксированные изменения не проблема, я не удаляю исходные данные, используемые для обновления, пока не буду уверен, что все в порядке кстати, уборщица сделала отключает сервер ДВАЖДЫ :-)
Некоторый поиск в Google показал, что это может помочь из-за проблемы, связанной с откатом сегментов, но я все еще не знаю эмпирического правила для N каждые несколько десятков?сотни?тысяча ?
@diciu :Большая информация, я обязательно посмотри на это.
Решение
Фиксация приводит к тому, что Oracle записывает данные на диск , т. е.в файле журнала повтора, чтобы все, что сделала совершаемая транзакция, можно было восстановить в случае сбоя питания и т.д.Запись в файл выполняется медленнее, чем запись в память, поэтому фиксация будет выполняться медленнее, если выполняется для многих операций подряд, а не для набора объединенных обновлений.
В Oracle 10g есть асинхронная фиксация, которая делает его намного быстрее, но менее надежным: https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6158695.html
PS Я точно знаю, что в сценарии, который я видел в определенном приложении, изменение количества объединенных обновлений с 5K до 50K ускоряет его на порядок (в 10 раз быстрее).
Другие советы
Уменьшение частоты фиксаций, безусловно, ускорит процесс, однако, поскольку вы часто читаете и записываете в эту таблицу, существует вероятность блокировок.Только вы можете определить вероятность того, что одни и те же данные будут обновлены в одно и то же время.Если вероятность этого невелика, фиксируйте каждые 50 строк и следите за ситуацией.Боюсь, методом проб и ошибок :-)
Помимо снижения частоты фиксации, вам также следует рассмотреть возможность выполнения массовых обновлений вместо отдельных.
Если вы "не удаляете исходные данные, используемые для обновления, пока не будете уверены, что все в порядке", то почему бы вам не удалить все эти промежуточные инкрементные коммиты и не выполнить откат, если возникнет проблема?Похоже, вы эффективно построили транзакционную систему поверх транзакций.
@CodeSlave на ваши вопросы отвечает @stevechol, если я удалю ВСЕ инкрементные коммиты, будут блокировки.Я думаю, если ничего лучшего не подвернется, я последую его совету, выберу случайное число, проконтролирую загрузку и соответствующим образом скорректирую.Во время нанесения @diciu подергивается.
PS:транзакция поверх транзакции происходит просто случайно, я получаю файлы, используемые для обновлений, по FTP, и вместо того, чтобы удалять их немедленно, я устанавливаю задание cron на удаление их через неделю (если никто, использующий приложение, не жаловался), это означает, что если что-то пойдет не так, у меня есть неделя, чтобы исправить ошибки.
Быстрее / Медленнее?
Вероятно, это будет немного быстрее.Однако вы подвергаетесь большему риску столкнуться с взаимоблокировками, потерей незафиксированных изменений, если произойдет что-то катастрофическое (уборщица отключает сервер), FUD, Fire, Brimstone и т.д.
Почему это должно помочь?
Очевидно, что меньше операций фиксации, что, в свою очередь, означает меньше операций записи на диск и т.д.
DBA и прямые ответы?
Если бы это было легко, вам бы это не понадобилось.