Изначальный запрос был вида:
select t_big.* from t_big where t_big.a=:aЕстественно, сразу захотелось распараллелить, но index range scan не идет в параллели, поэтому пришлось прибегнуть к небольшому ухищрению, которое позволило ускорить выполнение более чем в 13 раз при установке DOP в 16!
Метод прост: т.к.вычитка из индекса достаточно быстрая, то просто читаем и материализуем rowid через IRS, и затем уже в параллели идем к таблице через TABLE ACCESS BY USER ROWID.
Окончательный запрос:
with rids as( select--+ materialize rowid rid from t_big t1 where t1.a=:a ) select/*+ use_nl(rids t_big) */ t_big.* from t_big, rids where t_big.rowid=rids.rid
Создание констрейнтов в параллели:
По умолчанию при создании констрейнтов они валидируются не распараллеливаясь, что существенно замедляет процесс. Особенно учитывая, что обычно это происходит в технологические перерывы и ресурсов полно.. Решается же проблема просто: создавать их нужно с enable novalidate, и лишь затем отдельно включать enable validate:
alter table t1 add constraint fk_t1 foreign key(a) references t2(a) enable novalidate; alter table t1 modify constraint fk_t1 enable validate;UPD: Исправил на enable novalidate, т.к. как правильно заметил Тимур c disable не будет работать с unique и foreign key, а будет только для check constraints.
Comments
>Решается же проблема просто: создавать их нужно с disable, и лишь затем отдельно включать enable validate
Насколько я помню, так не будет работать "быстро". Надо создавать констрейнт в enable novalidate, и потом валидировать - тогда валидация будет выполняться без блокировок.
Про валидацию в параллель я писал тут: http://timurakhmadeev.wordpress.com/2011/02/16/enabling-constraint-in-parallel/
Спасибо, Тимур! А то я забыл исправить. Честно говоря, когда готовил скрипт писал с enable novalidate, а когда писал пост подумал, что и с disable сработает, а на следующий день проверил и обнаружил, что срабатывает так только для check constraints, а пост исправить забыл.
Отправить комментарий