В этом примере вместо полного сканирования таблицы используется индекс из-за того, как выделено пространство сегмента. По умолчанию Oracle стремится выделить нетривиальный объем пространства для разделов таблицы. Для индексов Oracle имеет тенденцию выделять гораздо меньше места для разделов индекса.
Когда я запускаю ваш пример кода, пустая таблица содержит 72 мегабайта, но пустой индекс содержит 0,5 мегабайта:
select segment_name, sum(bytes)/1024/1024 mb
from user_segments
where segment_name in ('T_TEST', 'PK_T_TEST')
group by segment_name
order by 1 desc;
SEGMENT_NAME MB
------------ -------
T_TEST 72
PK_T_TEST 0.5625
Полные сканы таблицы должны читать весь сегмент. Сканирование диапазона индекса все еще должно считывать данные из таблицы, но это можно сделать с помощью идентификаторов ROWID и, следовательно, считывать меньше данных с диска.
Автоматическое распределение пространства сегментов в Oracle почти всегда лучше, чем его настройка вручную. Но с тривиальным объемом данных может иметь смысл оптимизировать сегменты. Если вы измените каждый из 9 SEGMENT CREATION IMMEDIATE
на STORAGE (INITIAL 64K NEXT 64K)
, тогда разделы таблицы будут меньше, и план выполнения будет использовать полное сканирование таблицы. Но вы, вероятно, не хотите этого делать. Эта проблема, вероятно, связана только с использованием нереально небольшого выборочного набора данных.
Пространственные алгоритмы Oracle по понятным причинам оптимизированы для хранения больших объемов данных в разделах.
К сожалению, это, вероятно, не поможет вам в вашей реальной проблеме. Вы упомянули таблицу с 300 миллионами строк, и такой размер должен лучше работать с секционированием.
Но реальная проблема также может быть связана с проблемой пространства сегментов. Возможно, таблица имела 3 миллиарда строк и была удалена, но никогда не уменьшалась? Или, может быть, таблица была создана с сотнями разделов, большинство из которых пустые. Или, может быть, таблица была создана с какой-то нелепой ручной настройкой пространства.
При работе с большими таблицами часто приходится думать о сегментах и байтах, а не о количестве строк.