powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / RS с левой открытой границей читает пустые блоки индекса
52 сообщений из 52, показаны все 3 страниц
RS с левой открытой границей читает пустые блоки индекса
    #39472256
NLK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NLK
Гость
Oracle Database 10g Release 10.2.0.4.0

Имеется таблица
Код: plsql
1.
2.
create table tab(...., dt date, ...);
create index idx_tab_dt on tab(dt);


В таблицу с постоянной скоростью пишутся данные, в dt записывается текущая дата-время. Все записи, старше нескольких часов удаляются ежеминутно. То есть, в таблице не очень много данных, но довольно много блоков (на порядок больше, чем необходимо, чтобы эти данные сохранить), и данные расположены всюду неплотно. Аналогичная ситуация с индексом: листовых блоков (по all_indexes.leaf_blocks) около 10 тыс, что почти в 10 раз меньше, чем блоков в сегменте индекса (100 тыс), и в каждом живом блоке в среднем по 10 записей.

При выполнении запроса вида
Код: plsql
1.
select * from tab where dt < almost_sysdate


периодически (не всегда!) читаются почти все блоки из сегмента индекса, т.е. не только те 10 тыс, что указаны в all_indexes.leaf_blocks, но и остальные 90 тыс из сегмента индекса. Хотя если использовать запрос с закрытой левой границей (almost_sysdate -1/24 < dt < almost_sysdate), то ничего лишнего не читается. Причём, индекс периодически, раз в несколько дней, переключается из режима чтения "лишних" блоков в режим чтения только блоков с данными, а потом переключается обратно.

Вопрос: периодическое чтение пустых блоков - это нормальная ситуация? Почему так происходит?
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472363
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, это ненормально
И очень похоже, что таки где-то вставляется запись с нулевой (отрицательной, до н.э.) датой, что оставляет все промежуточные блоки в цепочке
Можно попробовать повесить констрейнт, типа дата не меньше чем год/месяц/день назад

Можно, конечно, грешить на баг, но 10.2.0.4 достаточно стабильная и описанная ситуация (добавление новых, подтирка старых) достаточно стандартная -- уже кто-нибудь наступил бы
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472441
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав ЛюбомудровНет, это ненормально
И очень похоже, что таки где-то вставляется запись с нулевой (отрицательной, до н.э.) датой, что оставляет все промежуточные блоки в цепочке
Да бог с тобой =)
Запись с маленькой датой оставит только блок в котором она есть, остальные блоки, в которых находятся только удаленные записи, будут переиспользованы по возможности.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472466
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сейчас точно не найду, но как-то проскакивала информация, что "в целях оптимизации" пустой блок становится недоступен через ссылочку из branch-блока, но цепочка "лево-право" не прерывается в листовых блоках, пока есть значение в конце цепочки. Только при переиспользовании этих пустых блоков указатели "лево-право" перезаписываются в смежные листовые блоки.
Вроде, как связано было с возможностью flashback по undo.
Врать уже больше не буду , но с определенной версии пришлось запускать ежесуточную перестройку индексов для приложения работающего в таком режиме "очереди"
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472475
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров,

Ну так алгоритм ТС будет постоянно переиспользовать пустые блоки
NLKВ таблицу с постоянной скоростью пишутся данные, в dt записывается текущая дата-время. Все записи, старше нескольких часов удаляются ежеминутно.
Так что записи в самом начале делу не помеха.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472507
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У нас затыкалась именно такая же технология -- "очередь", где накладывается в один конец, а вычищается (обрабатывается) с другого
Только там была не дата, а ID из последовательности
Вот когда обработка некоторых ID затыкалась -- их делали отрицательными (типа, разберемся потом)
И начинались тормоза, которые лечились ежесуточным перестроением индекса

Естественно, если ничего не трогать (не обновлять ID в отрицательное значение), то ничего и не тормозило, все красиво отрезалось и MIN/MAX не пробегал сотню пустых блоков

Вот точно не скажу, вроде как действительно началось именно в 10.2
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472515
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров,

Т.е. при каких-то условиях, индексные блоки с удаленными записями не использовались повторно в массовых количествах?
Весьма интересно.
Можешь пример представить?
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472524
Фотография DВА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NLKпериодически (не всегда!) читаются почти все блоки из сегмента индекса

а как читаются?
range scan?
fast full scan?
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472530
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFF__|Вячеслав Любомудров,

Т.е. при каких-то условиях, индексные блоки с удаленными записями не использовались повторно в массовых количествах?
Весьма интересно.
Можешь пример представить?Они использовались
И именно тогда цепочка укорачивалась
Но не так быстро, как хотелось бы

Пример так быстро не предоставлю, в отпуске, пишу по памяти

2DBA
Насколько помню, именно RS
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472539
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
NLKВопрос: периодическое чтение пустых блоков - это нормальная ситуация? Почему так происходит?да, скорее всего, у вас просто план плавает с фулскана на rs и обратно
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472561
NLK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NLK
Гость
DВАNLKпериодически (не всегда!) читаются почти все блоки из сегмента индекса

а как читаются?
range scan?
fast full scan?

dbms_xplan.display_cursor показывает INDEX RANGE SCAN.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472566
NLK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NLK
Гость
xtenderNLKВопрос: периодическое чтение пустых блоков - это нормальная ситуация? Почему так происходит?да, скорее всего, у вас просто план плавает с фулскана на rs и обратно
Но dbms_xplan.display_cursor ни разу не показывал фулсканы: в обоих "режимах" работы индекса показывает index range scan, только Buffers и Reads скачут на порядок.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472569
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NLK,

analyze index idx_tab_dt validate structure
select * from index_stats
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472573
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
NLKолько Buffers и Reads скачут на порядок.так а ожидания-то проверили? может не индекс-то читается, а просто совпадает с удалениями вашими постоянными
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472606
NLK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NLK
Гость
AlexFF__|NLK,

analyze index idx_tab_dt validate structure
select * from index_stats
Это ведь блокирующая операция. На боевой БД не дадут это сделать.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472612
NLK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NLK
Гость
xtenderNLKолько Buffers и Reads скачут на порядок.так а ожидания-то проверили? может не индекс-то читается, а просто совпадает с удалениями вашими постоянными
Прошу прощения, я видимо что-то не понял. Имеете в виду, что другой объект (таблица, а не индекс) читается? Или dbms_xplan.display_cursor показывает чтения и для других запросов, выполнявшихся одновременно с проблемным?
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472616
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
NLK,

я про undo
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472618
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
NLK,

ну и возможная отложенная очистка блоков
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472674
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да скорее всего, все проще
NLKАналогичная ситуация с индексом: листовых блоков (по all_indexes.leaf_blocks) около 10 тыс, что почти в 10 раз меньше, чем блоков в сегменте индекса (100 тыс), и в каждом живом блоке в среднем по 10 записей.
В индексе из примерно 100к блоков (не будем считать дерево) не пустые только 10к, они и показаны в статистике как leaf_blocks.
IRS (dt < almost_sysdate) в таком случае читает все пустые блоки в начале, (almost_sysdate -1/24 < dt < almost_sysdate) читает только нужный диапазон, выключая некоторые пустые блоки, по удаленным записям тоже определяются границы.
Только записи в данном случае должны писаться мощными блоками раз некоторое время =)
Или, как писал Вячеслав Любомудров, это какой-то баг при котором сводные блоки не используются повторно некоторое время.
В любом случае, как ты и сам писал, левая граница поможет.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472707
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
И все-таки для начала я бы зафиксировал план с IRS для надёжности...
Затем отребилдил бы индекс, т.к. похоже что сегмент такой большой, потому что изначально не было удаления по расписанию.
И только потом, если проблема осталась решал бы её по детальным данным с ожиданиями.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472757
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот навскидку описание изVarious Aspects of Fragmentation (Doc ID 186826.1)
Код: plaintext
1.
2.
3.
4.
5.
6.
4.  Fragmentation within B*Tree Segments
----------------------------------------
B*Trees get fragmented due to repeated DML operations.
...
4.2. On deletes,  if a leaf block becomes empty , it is put on the list of free 
     blocks.  It is not removed from the tree at this point  for performance
     reasons as this block might have a key inserted into it soon.
Т.е. пока блок не будет переиспользован, он так и останется в цепочке листовых блоков и при просмотре индекса (RANGE / FULL INDEX SCAN) будет читаться.
Естественно, если условие будет на ключ (например, дата > sysdate-1), а не просто
Код: plsql
1.
select * from (select /*+ index */ ... from table order by дата) where rownum <= 10

то начальное (MIN/MAX) значение (та самая нулевая дата) и все пустые блоке в цепочке до действительно нужной даты будут пропущены

PS. Правда, если у автора действительно NLKВсе записи, старше нескольких часов удаляются ежеминутното это не та причина.
Но это же sql.ru -- читаешь об одном, а отвечаешь про наболевшее
Да и есть подозрение, что удаляются только "обработанные" записи, а не скопом DELETE ... WHERE дата < sysdate-6/24

PPS. Тестик надо будет все-таки сделать, самому интересно
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39472758
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NLKAlexFF__|NLK,

analyze index idx_tab_dt validate structure
select * from index_stats
Это ведь блокирующая операция. На боевой БД не дадут это сделать.Если есть доступ, можно посмотреть Script to investigate a b-tree index structure (Doc ID 989186.1)
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473592
Nobody1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
NLKВ таблицу с постоянной скоростью пишутся данные, в dt записывается текущая дата-время. Все записи, старше нескольких часов удаляются ежеминутно. То есть, в таблице не очень много данных, но довольно много блоков (на порядок больше, чем необходимо, чтобы эти данные сохранить), и данные расположены всюду неплотно. Аналогичная ситуация с индексом: листовых блоков (по all_indexes.leaf_blocks) около 10 тыс, что почти в 10 раз меньше, чем блоков в сегменте индекса (100 тыс), и в каждом живом блоке в среднем по 10 записей.

При выполнении запроса вида
Код: plsql
1.
select * from tab where dt < almost_sysdate


периодически (не всегда!) читаются почти все блоки из сегмента индекса, т.е. не только те 10 тыс, что указаны в all_indexes.leaf_blocks, но и остальные 90 тыс из сегмента индекса. Хотя если использовать запрос с закрытой левой границей (almost_sysdate -1/24 < dt < almost_sysdate), то ничего лишнего не читается. Причём, индекс периодически, раз в несколько дней, переключается из режима чтения "лишних" блоков в режим чтения только блоков с данными, а потом переключается обратно.

Вопрос: периодическое чтение пустых блоков - это нормальная ситуация? Почему так происходит?
Предполагаю, что переключение в режим чтения только блоков с данными происходит после (автоматического) пересбора статистики по этой таблице. По мере того, как статистика (интервал , в котором на тот момент были значения dt) перестает соответствовать попаданию в этот интервал almost_sysdate, план портится.

xtenderда, скорее всего, у вас просто план плавает с фулскана на rs и обратно
+1

Наверное, зафиксировать план, как xtender предложил, будет наиболее разумно.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473610
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NLKВ таблицу с постоянной скоростью пишутся данные, в dt записывается текущая дата-время. Все записи, старше нескольких часов удаляются ежеминутно. То есть, в таблице не очень много данных, но довольно много блоков (на порядок больше, чем необходимо, чтобы эти данные сохранить), и данные расположены всюду неплотно. Аналогичная ситуация с индексом: листовых блоков (по all_indexes.leaf_blocks) около 10 тыс, что почти в 10 раз меньше, чем блоков в сегменте индекса (100 тыс), и в каждом живом блоке в среднем по 10 записей.В индексе, в котором данные монотонно сдвигаются "вправо", "левые" высвобождающиеся блоки повторно не используются, поскольку автоматический coalesce происходит только при попытке вставить околоудалённый ключ, чего в монотонно подчищающейся последовательности не происходит.
Как следствие RS слева (даже min) катастрофически неэффективен.
Выход несложный: после какого-то очередного массового delete надо делать индексу ничего не блокирующий coalesce.
Вячеслав ЛюбомудровИ начинались тормоза, которые лечились ежесуточным перестроением индексаСерпом по яйцам не разбираясь?
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473615
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicNLKВ таблицу с постоянной скоростью пишутся данные, в dt записывается текущая дата-время. Все записи, старше нескольких часов удаляются ежеминутно. То есть, в таблице не очень много данных, но довольно много блоков (на порядок больше, чем необходимо, чтобы эти данные сохранить), и данные расположены всюду неплотно. Аналогичная ситуация с индексом: листовых блоков (по all_indexes.leaf_blocks) около 10 тыс, что почти в 10 раз меньше, чем блоков в сегменте индекса (100 тыс), и в каждом живом блоке в среднем по 10 записей.В индексе, в котором данные монотонно сдвигаются "вправо", "левые" высвобождающиеся блоки повторно не используются, поскольку автоматический coalesce происходит только при попытке вставить околоудалённый ключ, чего в монотонно подчищающейся последовательности не происходит.
Как следствие RS слева (даже min) катастрофически неэффективен.Это не совсем так
Они переиспользуются, когда до них доходит очередь (а алгоритм там не совсем очевидный) -- сразу после того как [листовой] блок становится полностью пустым, он попадает в список свободных блоков, но из цепочки (лист <-> лист) не удаляется (до переиспользования)
Т.е. пустые блоки посещаются только при движении по листовым ссылкам
Более того, если у тебя в левом конце нет актуального значения, то в этот левый конец никак не попадешь (через путешествие по root->[branch->]...leaf)
Соответственно, обычное "скользящее" окно, если оно небольшое, работает достаточно предсказуемо
ElicВыход несложный: после какого-то очередного массового delete надо делать индексу ничего не блокирующий coalesce.Здесь нет "массового" удаления, здесь оно непрерывное
Очередь
ElicВячеслав ЛюбомудровИ начинались тормоза, которые лечились ежесуточным перестроением индексаСерпом по яйцам не разбираясь?В ранних версиях 10-ки, насколько помню с COALESCE был достаточно страшный баг, когда при его прерывании (на индексе ) можно было потерять данные таблицы . Да и кто юзает новые фичи сразу
По поводу перестроения тоже свои тараканы -- до 11 нельзя было указать таймаут DDL (а может это и хорошо было), а потом еще какие-то фишки с ONLINE вылезли
Когда это все работает асинхронно, в несколько потоков (как наваливающих, так и разгребающих) со своими связанными таблицами... В общем, как правило, работает
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473616
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderотребилдилДостаточно coalesce.
Да и сценарий стандартнейший. Не понимаю, почему широко не освещён.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473618
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав ЛюбомудровЭто не совсем так
Они переиспользуютсяНет. В "скользящем окне" левые блоки переиспользуются чуть реже, чем никогда. Поверь моему многодесятилетнему опыту. Только явный coalesce помогает.
Вячеслав ЛюбомудровЗдесь нет "массового" удаления, здесь оно непрерывное
ОчередьС точки зрения конечного результата - без разницы. Просто в таком случае не просто совместить coalesce с delete.
Вячеслав ЛюбомудровВ ранних версиях 10-ки, насколько помню с COALESCE был достаточно страшный баг, когда при его прерывании (на индексе ) можно было потерять данные таблицы .Не верю. coalesce всего лишь команда задействовать встроенные в индекс механизмы.
И поэтому никого не блокирует. Только на чуть-чуть в рамках конкретного блока.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473619
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicВячеслав ЛюбомудровЭто не совсем так
Они переиспользуютсяНет. В "скользящем окне" левые блоки переиспользуются чуть реже, чем никогда.И я тоже какое-то время верил в переиспользование. Но в случае скользящего окна оно не работает.
Даже, по-моему, у Льюиса об этом есть. Но не в столь явной форме, что при скользящем окне нужен регулярный coalesce.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473626
Фотография DВА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так версия 10.2, там усе может быть )
насчет данных таблицы хз, но вот данные индекса например при ребилд онлайн запросто теряются, обращаешься к таблице по индексу, а нет там ничего )
кстати и в 11 тоже воспроизводится, и в 12 )
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473627
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicВячеслав ЛюбомудровЭто не совсем так
Они переиспользуютсяНет. В "скользящем окне" левые блоки переиспользуются чуть реже, чем никогда. Поверь моему многодесятилетнему опыту. Только явный coalesce помогает.И все же это не так
У нас ежедневно в родительскую таблицу влетают сотни тысяч записей (и в дочерние соответственно миллионы), но при этом индексы не разрастаются, если вовремя разгребается (удаляется) то, что успело навалиться (вставиться)
Это работает много (более 10) лет, 24*7
Проблемы возникают когда где-то происходит затык и "обработчики" сильно отстают от "агентов" (или когда левая граница умышлено "замораживается" через отрицательный ID)
ElicВячеслав ЛюбомудровВ ранних версиях 10-ки, насколько помню с COALESCE был достаточно страшный баг, когда при его прерывании (на индексе ) можно было потерять данные таблицы .Не верю. coalesce всего лишь команда задействовать встроенные в индекс механизмы.
И поэтому никого не блокирует. Только на чуть-чуть в рамках конкретного блока.Скорее всего, я попутал со SHRINK (но поразило именно то, что упаковывается индекс , а данные можно потерять в таблице )
Предупреждение я увидел здесь (темку вот так сразу найти не удалось), а потом нашел этот баг на металинке
В общем, страшновато стало
А так один из обработчиков перед началом основной деятельности проверяет, что индексы не перестраивались уже сутки и делает попытку перестроить (а не получилось, ну так и бог с ним, попробуем в следующий раз) -- при нормальной работе это занимает секунды
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473629
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DВАно вот данные индекса например при ребилд онлайн запросто теряются, обращаешься к таблице по индексу, а нет там ничего )
кстати и в 11 тоже воспроизводится, и в 12 )Если запросто, то где тест-кэйс?
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473630
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DBA прикалывается
Естественно, при кривом индексе попасть через него в таблицу нельзя
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473631
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудровчерез отрицательный IDИменно это и могло провоцировать автоматический coalesce.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473632
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Именно это, как раз, и создает длиннющую цепочку пустых блоков, если мы идем от MIN ну и дальше по индексу
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473640
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав ЛюбомудровИменно это, как раз, и создает длиннющую цепочку пустых блоков, если мы идем от MIN ну и дальше по индексуТы не прав.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create table qz_tab as select trunc(sysdate) + level/24/60/60 as dt from dual connect by level <= 500000;
create index qz_tab$i$dt on qz_tab(dt);
analyze index qz_tab$i$dt validate structure;
select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;
delete qz_tab;
commit;
analyze index qz_tab$i$dt validate structure;
select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;
insert into qz_tab values (trunc(sysdate) + 500001/24/60/60);
commit;
analyze index qz_tab$i$dt validate structure;
select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;
set autot on
select min(dt) from qz_tab;
alter index qz_tab$i$dt coalesce;
select min(dt) from qz_tab;
set autot off
analyze index qz_tab$i$dt validate structure;
select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;

drop table qz_tab purge;


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
Elic@elic10>; create table qz_tab as select trunc(sysdate) + level/24/60/60 as dt from dual connect by level <= 500000;

Table created.

Elic@elic10>; create index qz_tab$i$dt on qz_tab(dt);

Index created.

Elic@elic10>; analyze index qz_tab$i$dt validate structure;

Index analyzed.

Elic@elic10>; select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;

      LF_ROWS       LF_BLKS       BR_ROWS       BR_BLKS   DEL_LF_ROWS
------------- ------------- ------------- ------------- -------------
       500000          1323          1322             4             0

1 row selected.

Elic@elic10>; delete qz_tab;

500000 rows deleted.

Elic@elic10>; commit;

Commit complete.

Elic@elic10>; analyze index qz_tab$i$dt validate structure;

Index analyzed.

Elic@elic10>; select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;

      LF_ROWS       LF_BLKS       BR_ROWS       BR_BLKS   DEL_LF_ROWS
------------- ------------- ------------- ------------- -------------
       400586          1323          1322             4        400586

1 row selected.

Elic@elic10>; insert into qz_tab values (trunc(sysdate) + 500001/24/60/60);

1 row created.

Elic@elic10>; commit;

Commit complete.

Elic@elic10>; analyze index qz_tab$i$dt validate structure;

Index analyzed.

Elic@elic10>; select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;

      LF_ROWS       LF_BLKS       BR_ROWS       BR_BLKS   DEL_LF_ROWS
------------- ------------- ------------- ------------- -------------
       400303          1323          1322             4        400302

1 row selected.

Elic@elic10>; set autot on
Elic@elic10>; select min(dt) from qz_tab;

MIN(DT)
-----------------
22.06.17 18:53:21

1 row selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1179258518

------------------------------------------------------------------------------------------
| Id  | Operation                  | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |             |     1 |     9 |   204   (0)| 00:00:03 |
|   1 |  SORT AGGREGATE            |             |     1 |     9 |            |          |
|   2 |   INDEX FULL SCAN (MIN/MAX)| QZ_TAB$I$DT |     1 |     9 |            |          |
------------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          4  recursive calls
          0  db block gets
       1397  consistent gets
         38  physical reads
        980  redo size
        519  bytes sent via SQL*Net to client
        488  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

Elic@elic10>; alter index qz_tab$i$dt coalesce;

Index altered.

Elic@elic10>; select min(dt) from qz_tab;

MIN(DT)
-----------------
22.06.17 18:53:21

1 row selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1179258518

------------------------------------------------------------------------------------------
| Id  | Operation                  | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |             |     1 |     9 |   204   (0)| 00:00:03 |
|   1 |  SORT AGGREGATE            |             |     1 |     9 |            |          |
|   2 |   INDEX FULL SCAN (MIN/MAX)| QZ_TAB$I$DT |     1 |     9 |            |          |
------------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        488  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

Elic@elic10>; set autot off
Elic@elic10>; analyze index qz_tab$i$dt validate structure;

Index analyzed.

Elic@elic10>; select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;

      LF_ROWS       LF_BLKS       BR_ROWS       BR_BLKS   DEL_LF_ROWS
------------- ------------- ------------- ------------- -------------
            1             1             0             2             0

1 row selected.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473646
Фотография DВА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic, в сапорте тест-кейс :)
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473697
Nobody1111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вячеслав ЛюбомудровПо поводу перестроения тоже свои тараканы -- до 11 нельзя было указать таймаут DDL (а может это и хорошо было), а потом еще какие-то фишки с ONLINE вылезли
"Веселые" фишки с ONLINE вылезали еще в 8i
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473728
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DВАElic, в сапорте тест-кейс :)Много пить - вредно.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473760
Фотография DВА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicDВАElic, в сапорте тест-кейс :)Много пить - вредно.
фантазировать на мой счет много вредно ))
Bug 7329252 : ORA-8102 DURING REBUILD INDEX ONLINE WHEN CONCURRENT W/ UPDATES
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473765
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
ElicДа и сценарий стандартнейший. Не понимаю, почему широко не освещён.лень искать, но я хорошо помню, что на асктоме кайт давным-давно писал про то что именно такие кейсы надо периодически ребилдил(он писал про AQ-таблицы - они как раз такой случай), только я никогда не проверял актуальность этого в разных версиях оракла...
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473766
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Точнее aq - это iot, но как раз постоянно вставляемые справа/удаляемые слева
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473933
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderлень искать, но я хорошо помню, что на асктоме кайтМало ли чего понапишут литературные рабы.xtenderдавным-давно писал про то что именно такие кейсы надо периодически ребилдилСаян, мне вот странно разъяснять такие, вроде как, очевидные вещи. Да если уж на то пошло, coalesce дешевле (по деньгам), чем rebuild online.Index Rebuild, the Need vs the Implications (Doc ID 989093.1)3. An index coalesce is often preferred instead of an index rebuild. It has the following advantages:
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39473935
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DВАBug 7329252Ната, я надеялся, что ты понимаешь, что тест-case - это не пустопорожние страшилки.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39474014
Фотография DВА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicDВАBug 7329252Ната, я надеялся, что ты понимаешь, что тест-case - это не пустопорожние страшилки.
Даже не знаю что тебе сказать... если зарегистрированный баг с выпущенным патчем - это пустопорожние страшилки :)
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39474021
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DВАДаже не знаю что тебе сказать... если зарегистрированный баг с выпущенным патчем - это пустопорожние страшилки :)Там слишком мало конкретики, что бы понять, а был ли предмет для боязни. Да и версии какие-то левенькие.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39474052
Фотография DВА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicDВАДаже не знаю что тебе сказать... если зарегистрированный баг с выпущенным патчем - это пустопорожние страшилки :)Там слишком мало конкретики, что бы понять, а был ли предмет для боязни. Да и версии какие-то левенькие.
Ну я не самый боязливый человек, но меня эта радость преследует периодически у разных заказчиков\работодателей, последний раз буквально полгода назад уже на 11.2 - при интенсивных апдейтах одних и тех же строк и параллельном перестраивание индекса в онлайне, либо перебрасывании партиций с апдейтом индексов в онлайне, в индексе теряются ключи для обновляемых строк. Для бага что я кинула под версию 10.2 тест-кейс элементарный, сама делала, но уже лет 8 назад, с 11.2 воспроизвести искусственно не получилось, видимо не все факторы учла, на на промышленной системе воспроизводился стабильно вплоть до наката патчсета и перехода на другую платформу, на 12 версии коллега показывал простенький тест-кейс, но там уже специфика связанная с недоработкой референс-партиционированных таблиц, баг 25898228, там вообще вся партиция уходит в никуда )
Так что бояться или не бояться дело добровольное, но иметь в виду стоит )
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39474073
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
ElicСаян, мне вот странно разъяснять такие, вроде как, очевидные вещи. Да если уж на то пошло, coalesce дешевле (по деньгам), чем rebuild online.1. Это было давным-давно, тогда coalesce и не было...
2. А ТСу я объяснил почему лучше разок сделать ребилд: я предположил, что т.к. размер сегмента у него минимум в 10 раз больше, чем нужно, то, видимо, удаления они сделали намного позднее, чем он так разросся.
Так что помимо самого просто так занимаемого места(которое, например, при IFFS будет зря сканироваться), это значит, что скорее всего ребилд и blevel может понизить.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39474075
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
ЗЫ. от Льюиса со ссылкой на вопрос на этот же форум: https://jonathanlewis.wordpress.com/2011/03/03/index-rebuilds-4/
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39474076
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
он, кстати, еще пишет:автор (Actually, "shrink space compact" seems to
be more efficient than "coalesce" in recent versions - but the whole AQ
thing introduces some funny effects around the edges anyway.)
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39485738
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет, поднимаем тему после отпуска =)
Алгоритм переиспользования пустых блоков индексов довольно интересен, будет жалко, если обсуждение закончится ничем.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE    11.2.0.4.0      Production
TNS for HPUX: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production


Давайте начнем с едиственного кейса в теме от Elic.
Я, к сожалению, не понял, что он хотел показать =(
В кейсе всталяются 500к записей, потом удаляются, затем справа вставляется еще одна запись.
Далее показывается, что INDEX FULL SCAN (MIN/MAX) сканирует всю цепочку листовых блоков, что естественно, скан ищет первую неудаленную запись.
Нас же интересует переиспользование этих пустых блоков, хорошо покажет это вставка 250к блоков (половина объемы) справа, т.е. возрастающая последовательность.
Я повторил кейс Elic, добавив в конце свои statements (для удобства чтения я опустил результаты, оставив последние значащие).
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
SQL> create table qz_tab as select trunc(sysdate) + level/24/60/60 as dt from dual connect by level <= 500000;
SQL> create index qz_tab$i$dt on qz_tab(dt);
SQL> analyze index qz_tab$i$dt validate structure;
SQL> select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;
SQL> delete qz_tab;
SQL> commit;
SQL> analyze index qz_tab$i$dt validate structure;
SQL> select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;
SQL> insert into qz_tab values (trunc(sysdate) + 500001/24/60/60);
SQL> commit;
SQL> analyze index qz_tab$i$dt validate structure;
SQL> select lf_rows, lf_blks, br_rows, br_blks, del_lf_rows from index_stats;
SQL> set autot on
SQL> select min(dt) from qz_tab;

MIN(DT)
---------------
15-JUL-17

Execution Plan
----------------------------------------------------------
Plan hash value: 2270586670
------------------------------------------------------------------------------------------
| Id  | Operation                  | Name        | Rows  | Bytes | Cost (%CPU)|Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |             |     1 |     9 |     3   (0)|00:00:01 |
|   1 |  SORT AGGREGATE            |             |     1 |     9 |            |         |
|   2 |   INDEX FULL SCAN (MIN/MAX)| QZ_TAB$I$DT |     1 |     9 |     3   (0)|00:00:01 |
------------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
          4  recursive calls
          0  db block gets
       2819  consistent gets
          0  physical reads
          0  redo size
        232  bytes sent via SQL*Net to client
        250  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> insert into qz_tab select date '2018-01-01' + level/24/60/60 as dt from dual connect by level <= 250000;
SQL> commit;
SQL> select min(dt) from qz_tab;

MIN(DT)
---------------
15-JUL-17

Execution Plan
----------------------------------------------------------
Plan hash value: 2270586670
------------------------------------------------------------------------------------------
| Id  | Operation                  | Name        | Rows  | Bytes | Cost (%CPU)|Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |             |     1 |     9 |     3   (0)|00:00:01 |
|   1 |  SORT AGGREGATE            |             |     1 |     9 |            |         |
|   2 |   INDEX FULL SCAN (MIN/MAX)| QZ_TAB$I$DT |     1 |     9 |     3   (0)|00:00:01 |
------------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1509  consistent gets
          0  physical reads
          0  redo size
        230  bytes sent via SQL*Net to client
        250  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed



Как видим, количество чтений упало почти в 2 раза с 2819 до 1509, что как раз и показывает переиспользование пустых блоков.

Далее уже мой старый тест, там идет вставка и последующее удаление разных диапазонов записей.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
declare
  procedure exec_dml( p_text in varchar2, p_sql in varchar2 ) is
  begin
    execute immediate p_sql;
    dbms_output.put_line( p_text || ' : ' || p_sql || ';' );
  end exec_dml;
  
  procedure exec_sql( p_sql in varchar2 ) is
    type t_tab is table of number;
    v_tab           t_tab;
    v_sql_id        varchar2(13);
    v_child_number  number;
    v_gets          number;
    v_info          varchar2(100);
  begin
    execute immediate p_sql bulk collect into v_tab;
    
    select sql_id, child_number into v_sql_id, v_child_number
      from ( select sql_id, child_number from v$sql where sql_text like p_sql || '%' order by last_active_time desc )
        where rownum = 1;
    
    select s.last_cr_buffer_gets + s.last_cu_buffer_gets, p.operation || ' ' || p.options into v_gets, v_info
      from v$sql_plan p, v$sql_plan_statistics s
        where p.sql_id = s.sql_id
          and p.child_number = s.child_number
          and p.address = s.address
          and p.child_address = s.child_address
          and p.id = s.operation_id
          and p.sql_id = v_sql_id
          and p.child_number = v_child_number
          and p.object_name = 'IDX_TEST';
    
    dbms_output.put_line( p_sql || ';' || ' rows = ' || to_char( v_tab.count ) || '; gets = ' || to_char( v_gets ) || ' [' || v_info || ']' );
  exception
    when others then
      dbms_output.put_line( p_sql || '; ' || SQLERRM );
  end exec_sql;
begin
  execute immediate 'alter session set statistics_level=all';
  
  execute immediate 'create table TAB_TEST( id number, text varchar2(20) )';
  execute immediate 'create index IDX_TEST on TAB_TEST( ID )';
  
  --===================================================================--
  
  exec_dml( lpad( '=', 100 ,'=' ) || chr(10) || '==== Очищаем таблицу', 'truncate table TAB_TEST' );
  exec_dml( '==== Вставляем 50000 записей', 'insert into TAB_TEST select rownum, ''test_'' || rownum from dual connect by rownum <= 50000' );
  exec_dml( '==== Удаляем 30000 записей в середине', 'delete TAB_TEST where id between 10001 and 40000' );
  commit;
  
  dbms_output.put_line( chr(10) || '--Читаются пустые блоки' );
  exec_sql( 'SELECT /* TEST 1.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001' );
  exec_sql( 'SELECT /* TEST 1.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001' );
  exec_sql( 'SELECT /* TEST 1.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001' );
  exec_sql( 'SELECT /* TEST 1.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001' );
  exec_sql( 'SELECT /*+ index(T IDX_TEST) TEST 1.5 */ ID FROM TAB_TEST T WHERE ID < 40010' );
  
  exec_dml( chr(10) || '==== Вставляем 20000 записей в конец', 'insert into TAB_TEST select rownum + 70000, ''test_'' || rownum from dual connect by rownum <= 20000' );
  commit;
  
  dbms_output.put_line( chr(10) || '--Часть пустых блоков переиспользованы повторно' );
  exec_sql( 'SELECT /* TEST 2.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001' );
  exec_sql( 'SELECT /* TEST 2.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001' );
  exec_sql( 'SELECT /* TEST 2.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001' );
  exec_sql( 'SELECT /* TEST 2.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001' );
  exec_sql( 'SELECT /*+ index(T IDX_TEST) TEST 2.5 */ ID FROM TAB_TEST T WHERE ID < 40010' );
  
  exec_dml( chr(10) || '==== Вставляем 20000 записей в конец', 'insert into TAB_TEST select rownum + 90000, ''test_'' || rownum from dual connect by rownum <= 20000' );
  commit;

  dbms_output.put_line( chr(10) || '--Пустые блоки переиспользованы повторно' );
  exec_sql( 'SELECT /* TEST 3.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001' );
  exec_sql( 'SELECT /* TEST 3.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001' );
  exec_sql( 'SELECT /* TEST 3.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001' );
  exec_sql( 'SELECT /* TEST 3.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001' );
  exec_sql( 'SELECT /*+ index(T IDX_TEST) TEST 3.5 */ ID FROM TAB_TEST T WHERE ID < 40010' );
  
  --===================================================================--
  
  exec_dml( chr(10) || chr(10) || lpad( '=', 100 ,'=' ) || chr(10) || '==== Очищаем таблицу', 'truncate table TAB_TEST' );
  exec_dml( '==== Вставляем 50000 записей', 'insert into TAB_TEST select rownum, ''test_'' || rownum from dual connect by rownum <= 50000' );
  exec_dml( '==== Удаляем 30000 записей в начале', 'delete TAB_TEST where id between 1 and 30000' );
  commit;
  
  dbms_output.put_line( chr(10) || '--Читаются пустые блоки' );
  exec_sql( 'SELECT /* TEST 4.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001' );
  exec_sql( 'SELECT /* TEST 4.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001' );
  exec_sql( 'SELECT /* TEST 4.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001' );
  exec_sql( 'SELECT /* TEST 4.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001' );
  exec_sql( 'SELECT /*+ index(T IDX_TEST) TEST 4.5 */ ID FROM TAB_TEST T WHERE ID < 30010' );
  
  exec_dml( chr(10) || '==== Вставляем 20000 записей в конец', 'insert into TAB_TEST select rownum + 70000, ''test_'' || rownum from dual connect by rownum <= 20000' );
  commit;
  
  dbms_output.put_line( chr(10) || '--Часть пустых блоков переиспользованы повторно' );
  exec_sql( 'SELECT /* TEST 5.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001' );
  exec_sql( 'SELECT /* TEST 5.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001' );
  exec_sql( 'SELECT /* TEST 5.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001' );
  exec_sql( 'SELECT /* TEST 5.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001' );
  exec_sql( 'SELECT /*+ index(T IDX_TEST) TEST 5.5 */ ID FROM TAB_TEST T WHERE ID < 30010' );
  
  exec_dml( chr(10) || '==== Вставляем 20000 записей в конец', 'insert into TAB_TEST select rownum + 90000, ''test_'' || rownum from dual connect by rownum <= 20000' );
  commit;

  dbms_output.put_line( chr(10) || '--Пустые блоки переиспользованы повторно' );
  exec_sql( 'SELECT /* TEST 6.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001' );
  exec_sql( 'SELECT /* TEST 6.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001' );
  exec_sql( 'SELECT /* TEST 6.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001' );
  exec_sql( 'SELECT /* TEST 6.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001' );
  exec_sql( 'SELECT /*+ index(T IDX_TEST) TEST 6.5 */ ID FROM TAB_TEST T WHERE ID < 30010' );
  
  --===================================================================--
  
  exec_dml( chr(10) || chr(10) || lpad( '=', 100 ,'=' ) || chr(10) || '==== Очищаем таблицу', 'truncate table TAB_TEST' );
  exec_dml( '==== Вставляем 50000 записей', 'insert into TAB_TEST select rownum, ''test_'' || rownum from dual connect by rownum <= 50000' );
  exec_dml( '==== Удаляем все 50000 записей', 'delete TAB_TEST' );
  commit;
  
  dbms_output.put_line( chr(10) || '--Читаются пустые блоки' );
  exec_sql( 'SELECT /* TEST 7.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001' );
  exec_sql( 'SELECT /* TEST 7.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001' );
  exec_sql( 'SELECT /* TEST 7.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001' );
  exec_sql( 'SELECT /* TEST 7.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001' );
  exec_sql( 'SELECT /*+ index(T IDX_TEST) TEST 7.5 */ ID FROM TAB_TEST T WHERE ID < 30010' );
  
  exec_dml( chr(10) || '==== Вставляем 20000 записей в конец', 'insert into TAB_TEST select rownum + 70000, ''test_'' || rownum from dual connect by rownum <= 20000' );
  commit;
  
  dbms_output.put_line( chr(10) || '--Часть пустых блоков переиспользованы повторно' );
  exec_sql( 'SELECT /* TEST 8.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001' );
  exec_sql( 'SELECT /* TEST 8.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001' );
  exec_sql( 'SELECT /* TEST 8.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001' );
  exec_sql( 'SELECT /* TEST 8.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001' );
  exec_sql( 'SELECT /*+ index(T IDX_TEST) TEST 8.5 */ ID FROM TAB_TEST T WHERE ID < 30010' );
  
  exec_dml( chr(10) || '==== Вставляем 30000 записей в конец', 'insert into TAB_TEST select rownum + 90000, ''test_'' || rownum from dual connect by rownum <= 30000' );
  commit;

  dbms_output.put_line( chr(10) || '--Пустые блоки переиспользованы повторно' );
  exec_sql( 'SELECT /* TEST 9.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001' );
  exec_sql( 'SELECT /* TEST 9.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001' );
  exec_sql( 'SELECT /* TEST 9.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001' );
  exec_sql( 'SELECT /* TEST 9.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001' );
  exec_sql( 'SELECT /*+ index(T IDX_TEST) TEST 9.5 */ ID FROM TAB_TEST T WHERE ID < 30010' );
  
  --===================================================================--
  
  execute immediate 'drop table TAB_TEST';
end;
/


Результаты:
====================================================================================================
==== Очищаем таблицу : truncate table TAB_TEST;
==== Вставляем 50000 записей : insert into TAB_TEST select rownum, 'test_' || rownum from dual connect by rownum <= 50000;
==== Удаляем 30000 записей в середине : delete TAB_TEST where id between 10001 and 40000;

--Читаются пустые блоки
SELECT /* TEST 1.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001; rows = 2; gets = 126 [INDEX RANGE SCAN]
SELECT /* TEST 1.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001; rows = 1; gets = 43 [INDEX RANGE SCAN]
SELECT /* TEST 1.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001; rows = 1; gets = 85 [INDEX RANGE SCAN]
SELECT /* TEST 1.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001; rows = 0; gets = 44 [INDEX RANGE SCAN]
SELECT /*+ index(T IDX_TEST) TEST 1.5 */ ID FROM TAB_TEST T WHERE ID < 40010; rows = 10009; gets = 164 [INDEX RANGE SCAN]

==== Вставляем 20000 записей в конец : insert into TAB_TEST select rownum + 70000, 'test_' || rownum from dual connect by rownum <= 20000;

--Часть пустых блоков переиспользованы повторно
SELECT /* TEST 2.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001; rows = 2; gets = 46 [INDEX RANGE SCAN]
SELECT /* TEST 2.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001; rows = 1; gets = 8 [INDEX RANGE SCAN]
SELECT /* TEST 2.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001; rows = 1; gets = 45 [INDEX RANGE SCAN]
SELECT /* TEST 2.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001; rows = 0; gets = 39 [INDEX RANGE SCAN]
SELECT /*+ index(T IDX_TEST) TEST 2.5 */ ID FROM TAB_TEST T WHERE ID < 40010; rows = 10009; gets = 84 [INDEX RANGE SCAN]

==== Вставляем 20000 записей в конец : insert into TAB_TEST select rownum + 90000, 'test_' || rownum from dual connect by rownum <= 20000;

--Пустые блоки переиспользованы повторно
SELECT /* TEST 3.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001; rows = 2; gets = 3 [INDEX RANGE SCAN]
SELECT /* TEST 3.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001; rows = 1; gets = 3 [INDEX RANGE SCAN]
SELECT /* TEST 3.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001; rows = 1; gets = 3 [INDEX RANGE SCAN]
SELECT /* TEST 3.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001; rows = 0; gets = 3 [INDEX RANGE SCAN]
SELECT /*+ index(T IDX_TEST) TEST 3.5 */ ID FROM TAB_TEST T WHERE ID < 40010; rows = 10009; gets = 41 [INDEX RANGE SCAN]


====================================================================================================
==== Очищаем таблицу : truncate table TAB_TEST;
==== Вставляем 50000 записей : insert into TAB_TEST select rownum, 'test_' || rownum from dual connect by rownum <= 50000;
==== Удаляем 30000 записей в начале : delete TAB_TEST where id between 1 and 30000;

--Читаются пустые блоки
SELECT /* TEST 4.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001; rows = 10001; gets = 250 [INDEX FAST FULL SCAN]
SELECT /* TEST 4.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001; rows = 0; gets = 43 [INDEX RANGE SCAN]
SELECT /* TEST 4.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001; rows = 1; gets = 85 [INDEX RANGE SCAN]
SELECT /* TEST 4.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001; rows = 1; gets = 44 [INDEX RANGE SCAN]
SELECT /*+ index(T IDX_TEST) TEST 4.5 */ ID FROM TAB_TEST T WHERE ID < 30010; rows = 9; gets = 123 [INDEX RANGE SCAN]

==== Вставляем 20000 записей в конец : insert into TAB_TEST select rownum + 70000, 'test_' || rownum from dual connect by rownum <= 20000;

--Часть пустых блоков переиспользованы повторно
SELECT /* TEST 5.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001; rows = 10001; gets = 212 [INDEX FAST FULL SCAN]
SELECT /* TEST 5.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001; rows = 0; gets = 35 [INDEX RANGE SCAN]
SELECT /* TEST 5.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001; rows = 1; gets = 43 [INDEX RANGE SCAN]
SELECT /* TEST 5.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001; rows = 1; gets = 10 [INDEX RANGE SCAN]
SELECT /*+ index(T IDX_TEST) TEST 5.5 */ ID FROM TAB_TEST T WHERE ID < 30010; rows = 9; gets = 43 [INDEX RANGE SCAN]

==== Вставляем 20000 записей в конец : insert into TAB_TEST select rownum + 90000, 'test_' || rownum from dual connect by rownum <= 20000;

--Пустые блоки переиспользованы повторно
SELECT /* TEST 6.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001; rows = 10001; gets = 282 [INDEX FAST FULL SCAN]
SELECT /* TEST 6.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001; rows = 0; gets = 2 [INDEX RANGE SCAN]
SELECT /* TEST 6.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001; rows = 1; gets = 2 [INDEX RANGE SCAN]
SELECT /* TEST 6.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001; rows = 1; gets = 2 [INDEX RANGE SCAN]
SELECT /*+ index(T IDX_TEST) TEST 6.5 */ ID FROM TAB_TEST T WHERE ID < 30010; rows = 9; gets = 2 [INDEX RANGE SCAN]


====================================================================================================
==== Очищаем таблицу : truncate table TAB_TEST;
==== Вставляем 50000 записей : insert into TAB_TEST select rownum, 'test_' || rownum from dual connect by rownum <= 50000;
==== Удаляем все 50000 записей : delete TAB_TEST;

--Читаются пустые блоки
SELECT /* TEST 7.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001; rows = 0; gets = 126 [INDEX RANGE SCAN]
SELECT /* TEST 7.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001; rows = 0; gets = 43 [INDEX RANGE SCAN]
SELECT /* TEST 7.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001; rows = 0; gets = 85 [INDEX RANGE SCAN]
SELECT /* TEST 7.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001; rows = 0; gets = 44 [INDEX RANGE SCAN]
SELECT /*+ index(T IDX_TEST) TEST 7.5 */ ID FROM TAB_TEST T WHERE ID < 30010; rows = 0; gets = 123 [INDEX RANGE SCAN]

==== Вставляем 20000 записей в конец : insert into TAB_TEST select rownum + 70000, 'test_' || rownum from dual connect by rownum <= 20000;

--Часть пустых блоков переиспользованы повторно
SELECT /* TEST 8.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001; rows = 0; gets = 89 [INDEX RANGE SCAN]
SELECT /* TEST 8.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001; rows = 0; gets = 33 [INDEX RANGE SCAN]
SELECT /* TEST 8.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001; rows = 0; gets = 50 [INDEX RANGE SCAN]
SELECT /* TEST 8.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001; rows = 0; gets = 21 [INDEX RANGE SCAN]
SELECT /*+ index(T IDX_TEST) TEST 8.5 */ ID FROM TAB_TEST T WHERE ID < 30010; rows = 0; gets = 71 [INDEX RANGE SCAN]

==== Вставляем 30000 записей в конец : insert into TAB_TEST select rownum + 90000, 'test_' || rownum from dual connect by rownum <= 30000;

--Пустые блоки переиспользованы повторно
SELECT /* TEST 9.1 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 40001; rows = 0; gets = 2 [INDEX RANGE SCAN]
SELECT /* TEST 9.2 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 20001; rows = 0; gets = 2 [INDEX RANGE SCAN]
SELECT /* TEST 9.3 */ ID FROM TAB_TEST WHERE ID BETWEEN 10000 AND 30001; rows = 0; gets = 2 [INDEX RANGE SCAN]
SELECT /* TEST 9.4 */ ID FROM TAB_TEST WHERE ID BETWEEN 20000 AND 30001; rows = 0; gets = 2 [INDEX RANGE SCAN]
SELECT /*+ index(T IDX_TEST) TEST 9.5 */ ID FROM TAB_TEST T WHERE ID < 30010; rows = 0; gets = 2 [INDEX RANGE SCAN]


И + еще накидал один дополнительно, тут вставляются в таблицу начальные 10000 значений, далее идут вставки в конец по 1000 и удаление сначала также по 1000 (500 итераций).
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
declare
  v_ins_cnt  number := 0;
  v_del_cnt  number := 0;
  
  procedure put_index_stats( p_num in number, p_ins_cnt in number, p_del_cnt in number ) is
  begin
    execute immediate 'analyze index IDX_TEST validate structure';
    
    for j in ( select height, blocks, lf_blks, lf_rows, br_blks, br_rows, del_lf_rows from index_stats ins where name = 'IDX_TEST' )
    loop
      dbms_output.put_line( lpad( p_num, 3, ' ' ) || '. blocks=' || to_char( j.blocks ) || ' lf_blks=' || to_char( j.lf_blks ) ||
                            ' lf_rows=' || to_char( j.lf_rows ) || ' br_blks=' || to_char( j.br_blks ) || ' br_rows=' || to_char( j.br_rows ) ||
                            ' del_lf_rows=' || to_char( j.del_lf_rows ) ||  ' [ins_cnt=' || to_char( p_ins_cnt ) || ' del_cnt=' || to_char( p_del_cnt ) || ']' );
    end loop;
  end put_index_stats;
begin
  execute immediate 'create table TAB_TEST( id number, text varchar2(20) )';
  execute immediate 'create index IDX_TEST on TAB_TEST( ID )';
  
  execute immediate 'insert into TAB_TEST select rownum, ''test_'' || rownum from dual connect by rownum <= 10000';
  
  for i in 1..500
  loop
    execute immediate 'insert into TAB_TEST select 10000 + rownum + ( ' || i || ' - 1 ) * 1000, ''test_'' || rownum from dual connect by rownum <= 1000';
    v_ins_cnt := v_ins_cnt + sql%rowcount;
    commit;
    
    execute immediate 'delete TAB_TEST where ID < ' || i || ' * 1000';
    v_del_cnt := v_del_cnt + sql%rowcount;
    commit;
    
    if mod( i, 10 ) = 0 then
      put_index_stats( i, v_ins_cnt, v_del_cnt );
      v_ins_cnt := 0;
      v_del_cnt := 0;
    end if;
  end loop;
  
  execute immediate 'drop table TAB_TEST';
end;
/


Результаты:

10. blocks=96 lf_blks=74 lf_rows=17123 br_blks=1 br_rows=73 del_lf_rows=7122 [ins_cnt=10000 del_cnt=9999]
20. blocks=96 lf_blks=87 lf_rows=19044 br_blks=1 br_rows=86 del_lf_rows=9043 [ins_cnt=10000 del_cnt=10000]
30. blocks=128 lf_blks=92 lf_rows=20526 br_blks=1 br_rows=91 del_lf_rows=10525 [ins_cnt=10000 del_cnt=10000]
40. blocks=128 lf_blks=92 lf_rows=20648 br_blks=1 br_rows=91 del_lf_rows=10647 [ins_cnt=10000 del_cnt=10000]
50. blocks=128 lf_blks=113 lf_rows=24436 br_blks=1 br_rows=112 del_lf_rows=14435 [ins_cnt=10000 del_cnt=10000]
60. blocks=128 lf_blks=114 lf_rows=24808 br_blks=1 br_rows=113 del_lf_rows=14807 [ins_cnt=10000 del_cnt=10000]
70. blocks=160 lf_blks=141 lf_rows=30302 br_blks=1 br_rows=140 del_lf_rows=20301 [ins_cnt=10000 del_cnt=10000]
80. blocks=160 lf_blks=147 lf_rows=30768 br_blks=1 br_rows=146 del_lf_rows=20767 [ins_cnt=10000 del_cnt=10000]
90. blocks=160 lf_blks=147 lf_rows=31610 br_blks=1 br_rows=146 del_lf_rows=21609 [ins_cnt=10000 del_cnt=10000]
100. blocks=192 lf_blks=148 lf_rows=32154 br_blks=1 br_rows=147 del_lf_rows=22153 [ins_cnt=10000 del_cnt=10000]
110. blocks=192 lf_blks=159 lf_rows=34021 br_blks=1 br_rows=158 del_lf_rows=24020 [ins_cnt=10000 del_cnt=10000]
120. blocks=192 lf_blks=177 lf_rows=37257 br_blks=1 br_rows=176 del_lf_rows=27256 [ins_cnt=10000 del_cnt=10000]
130. blocks=192 lf_blks=177 lf_rows=37554 br_blks=1 br_rows=176 del_lf_rows=27553 [ins_cnt=10000 del_cnt=10000]
140. blocks=192 lf_blks=177 lf_rows=37954 br_blks=1 br_rows=176 del_lf_rows=27953 [ins_cnt=10000 del_cnt=10000]
150. blocks=224 lf_blks=191 lf_rows=40871 br_blks=1 br_rows=190 del_lf_rows=30870 [ins_cnt=10000 del_cnt=10000]
160. blocks=224 lf_blks=205 lf_rows=43230 br_blks=1 br_rows=204 del_lf_rows=33229 [ins_cnt=10000 del_cnt=10000]
170. blocks=224 lf_blks=207 lf_rows=42956 br_blks=1 br_rows=206 del_lf_rows=32955 [ins_cnt=10000 del_cnt=10000]
180. blocks=224 lf_blks=207 lf_rows=42345 br_blks=1 br_rows=206 del_lf_rows=32344 [ins_cnt=10000 del_cnt=10000]
190. blocks=224 lf_blks=207 lf_rows=42732 br_blks=1 br_rows=206 del_lf_rows=32731 [ins_cnt=10000 del_cnt=10000]
200. blocks=256 lf_blks=208 lf_rows=43525 br_blks=1 br_rows=207 del_lf_rows=33524 [ins_cnt=10000 del_cnt=10000]
210. blocks=256 lf_blks=208 lf_rows=43168 br_blks=1 br_rows=207 del_lf_rows=33167 [ins_cnt=10000 del_cnt=10000]
220. blocks=256 lf_blks=208 lf_rows=43211 br_blks=1 br_rows=207 del_lf_rows=33210 [ins_cnt=10000 del_cnt=10000]
230. blocks=256 lf_blks=208 lf_rows=42597 br_blks=1 br_rows=207 del_lf_rows=32596 [ins_cnt=10000 del_cnt=10000]
240. blocks=256 lf_blks=208 lf_rows=42143 br_blks=1 br_rows=207 del_lf_rows=32142 [ins_cnt=10000 del_cnt=10000]
250. blocks=256 lf_blks=208 lf_rows=42607 br_blks=1 br_rows=207 del_lf_rows=32606 [ins_cnt=10000 del_cnt=10000]
260. blocks=256 lf_blks=208 lf_rows=43126 br_blks=1 br_rows=207 del_lf_rows=33125 [ins_cnt=10000 del_cnt=10000]
270. blocks=256 lf_blks=229 lf_rows=47697 br_blks=1 br_rows=228 del_lf_rows=37696 [ins_cnt=10000 del_cnt=10000]
280. blocks=256 lf_blks=238 lf_rows=49974 br_blks=1 br_rows=237 del_lf_rows=39973 [ins_cnt=10000 del_cnt=10000]
290. blocks=288 lf_blks=238 lf_rows=49170 br_blks=1 br_rows=237 del_lf_rows=39169 [ins_cnt=10000 del_cnt=10000]
300. blocks=288 lf_blks=238 lf_rows=48596 br_blks=1 br_rows=237 del_lf_rows=38595 [ins_cnt=10000 del_cnt=10000]
310. blocks=288 lf_blks=238 lf_rows=48443 br_blks=1 br_rows=237 del_lf_rows=38442 [ins_cnt=10000 del_cnt=10000]
320. blocks=288 lf_blks=242 lf_rows=48379 br_blks=1 br_rows=241 del_lf_rows=38378 [ins_cnt=10000 del_cnt=10000]
330. blocks=288 lf_blks=251 lf_rows=48937 br_blks=1 br_rows=250 del_lf_rows=38936 [ins_cnt=10000 del_cnt=10000]
340. blocks=288 lf_blks=252 lf_rows=49602 br_blks=1 br_rows=251 del_lf_rows=39601 [ins_cnt=10000 del_cnt=10000]
350. blocks=288 lf_blks=254 lf_rows=49987 br_blks=1 br_rows=253 del_lf_rows=39986 [ins_cnt=10000 del_cnt=10000]
360. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
370. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
380. blocks=288 lf_blks=262 lf_rows=52799 br_blks=1 br_rows=261 del_lf_rows=42798 [ins_cnt=10000 del_cnt=10000]
390. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
400. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
410. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
420. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
430. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
440. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
450. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
460. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
470. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
480. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
490. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]
500. blocks=288 lf_blks=262 lf_rows=52557 br_blks=1 br_rows=261 del_lf_rows=42556 [ins_cnt=10000 del_cnt=10000]

Тут видно, что хотя размер и растет постоянно, но алгоритм переиспользования пустых блоков работает.
Для сравнения, размер индекса без удаления записей (т.е. имуляция того, что пустые блоки остаются навсегда) - 2105 lf_blks.
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39485764
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFF__|но алгоритм переиспользования пустых блоков работает.Но по сравнению с coalesce - "не очень" и по-прежнему неэффективно для запросов "слева".
...
Рейтинг: 0 / 0
RS с левой открытой границей читает пустые блоки индекса
    #39621991
efendi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
[quot DВА]Elicпропущено...... на 12 версии коллега показывал простенький тест-кейс, но там уже специфика связанная с недоработкой референс-партиционированных таблиц, баг 25898228, там вообще вся партиция уходит в никуда ...

А можно узнать подробности: сам тест-кейс, описание бага, как решали проблему, был ли пачсет?
Возникла похожая ситуация - после добавления секции слетел глобальный индекс, не видел новую секцию.

Спасибо.
...
Рейтинг: 0 / 0
52 сообщений из 52, показаны все 3 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / RS с левой открытой границей читает пустые блоки индекса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]