softwarer
Member
Откуда: Москва
Сообщений: 24460
|
Подскажите, чем можно исправить следующую ситуацию.
Есть Oracle 9, табличка примерно на 10.000.000 записей. Нужно пройти ее по порядку, обработав каждую запись (точнее - в общем случае обработать не обработанные ранее записи).
Для этого я делаю следующий запрос:
select *
from ldr$invoices
where invoice_id > :start_invoice_id
order by invoice_id
|
|
Стартовое значение для начала принимает id'шник последней обработанной записи; чтобы не попасть в shapshot too old, запрос время от времени переоткрывается с новым стартовым id-шником. invoice_id - первичный ключ, и, с моей точки зрения, первые записи такой запрос должен возвращать мгновенно.
Проблема же в том, что этот запрос выполняется очень долго и не желает оптимизиться. В таком виде, а также с хинтами типа first_rows, оракл упорно строит план с table full scan / sort order by. Что, как ни странно, несколько напрягает сервер :-)
Если явно вставить хинтом использование индекса, план меняется на index full scan / table access by index / sort order by, результаты не лучше, что опять-таки неудивительно.
С восьмым ораклом я не припомню, чтобы в такой ситуации возникали какие-либо проблемы. В целом, полагаю, это недоработка по настройке сервера, а не серверный глюк.
Эксперименты показывают следующее: во-первых, если убрать where, план остается тем же. То есть - даже при select * from ldr$invoices order by invoice_id сервер не пытается использовать индекс по invoice_id - что, имхо, крайне странно. Во-вторых, если сделать просто select * from ldr$invoices, первая порция возвращается мгновенно, но в довольно странном порядке - при том, что id-шники выдавались плотно и по порядку, запрос возвращает их примерно так:
1000001
2000001
....
9000001
1000100
2000100
....
впрочем, полагаю, это может быть следствием загрузки данных через sql*loader.
Что еще может оказать влияние. Таблицы анализируются следующим джобиком:
begin
dbms_stats.gather_schema_stats (
ownname => 'LOADER',
estimate_percent => dbms_stats.auto_sample_size,
degree => dbms_stats.default_degree,
cascade => true ) ;
dbms_stats.gather_schema_stats (
ownname => 'WAREHOUSE',
estimate_percent => dbms_stats.auto_sample_size,
degree => dbms_stats.default_degree,
cascade => true ) ;
end ;
|
|
У сервера выставлен optimizer_mode choose (впрочем, смена режима хинтами не спасает). |