SQL.RU
 client/server technologies
 
 Главная | Документация | Статьи | Книги | Форум | Опросы | Рассылка | Работа | Поиск | FAQ |

Добро пожаловать в форум, Guest  >>  Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик  Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Oracle9i: плохо выполняется простой запрос   [new]
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 (впрочем, смена режима хинтами не спасает).
16 мар 04, 11:01    [579675] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Animal
Member

Откуда:
Сообщений: 525
План запроса в студию.


ЗЫ
Какой патч стоит?
16 мар 04, 11:10    [579702] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Scott Tiger
Member

Откуда: Солнышко
Сообщений: 6093
А чего удивляться? Во-первых, мне думается, что запрос выдаёт относительно большое количество записей, что, с учётом применяемой сортировки по invoice_id вырождается в небыстрые сортировки на диске. Во-вторых, зачем-то выбирается *, а не только нужные колонки, что исключает использование FFS. В-третьих, "просто" селект выдаст данные в неопределённом порядке, и гарантировать определённый порядок можно только с использованием конструкции order by. Использование/неиспользование индекса также зависит от ряда параметров настройки сервера/сессии, влияющих на стоимость планов CBO (optimizer_*, *_multiblock_read_count). Ну и, наконец, статистику стоит собирать полностью, если есть возможность.
16 мар 04, 11:12    [579708] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Animal
Member

Откуда:
Сообщений: 525
полностью Согласен с Тигром.


ЗЫ
select * from ldr$invoices order by invoice_id
И вообще почему это индекс должен отрабатывать при данном запросе, если все равно выбираются все записи?
По скорости будет как раз лучше full scan.
И вся фигня вешается чисто из-за сортировки (из-за недостаточности ресурсов и(или) их оптимизации) .
16 мар 04, 11:16    [579727] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
План запроса в студию.


Хм. Он написан в исходном сообщении

SORT ORDER BY
|
+-- TABLE ACCESS BY INDEX ROWID
|
+-- INDEX FULL SCAN


Для варианта с хинтом по индексу; без него TABLE FULL SCAN вместо двух первых шагов.

Какой патч стоит?


Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

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

Именно. И я решительно не понимаю, почему сервер использует сортировку на диске вместо того, чтобы спокойно пройти по существующему индексу. Могу ошибиться в терминах, но я бы ожидал плана вида

FILTER
INDEX FULL SCAN

с соответствующей скоростью работы.

Во-вторых, зачем-то выбирается *, а не только нужные колонки, что исключает использование FFS.

Хм. Полагаешь, я стал бы держать в этой таблице колонки, которые мне не нужны? Или оракл станет работать лучше, если аккуратно перечислить имена всех колонок?

В-третьих, "просто" селект выдаст данные в неопределённом порядке, и гарантировать определённый порядок можно только с использованием конструкции order by.

Правильно. При этом - на практике - TABLE FULL SCAN выдает записи согласно их расположению в блоках, то есть при вставке по порядку и отсутствии удалений в таком порядке и выдает. Другой порядок записей означает либо странное расположение по блокам (что может быть следствием "параллельных" возможностей SQL*Loader), либо еще что-либо, мне неизвестное, но возможно известное другим и влияющее на ситуацию.

Использование/неиспользование индекса также зависит от ряда параметров настройки сервера/сессии, влияющих на стоимость планов CBO (optimizer_*, *_multiblock_read_count).

Хорошо. Но почему он даже при явном указании хинта не использует нормально индекс? И как его убедить это сделать?

Ну и, наконец, статистику стоит собирать полностью, если есть возможность

Оно понятно. Но эта таблица не одна такая, и в реальной эксплуатации в ней будут скорее сотни миллионов записей. У меня есть впечатление, что на полную статистику через какое-то время перестанет хватать ночи :-)
16 мар 04, 11:39    [579801] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
select * from ldr$invoices order by invoice_id
И вообще почему это индекс должен отрабатывать при данном запросе, если все равно выбираются все записи?
По скорости будет как раз лучше full scan.
И вся фигня вешается чисто из-за сортировки (из-за недостаточности ресурсов и(или) их оптимизации) .

:-)

select /*+ first_rows */ *
from mytable
order by myindexedfield

Ты серьезно уверен, что table full scan в таком случае лучше, нежели index full scan? Обоснуешь? Для таблицы с 10.000.000 записей? Обратив внимание на first_rows?
16 мар 04, 11:46    [579826] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Animal
Member

Откуда:
Сообщений: 525
Хм. Он написан в исходном сообщении


Еще раз просмотрел, так и не увидел
16 мар 04, 11:55    [579868] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Sir
Member

Откуда:
Сообщений: 289
Есть не совсем корректное предложение.
Убрать ORDER BY.

select *
from ldr$invoices
where invoice_id > :start_invoice_id

и для уверенности поставить хинт, чтобы использовался индекс.
Тогда сортировки удастся избежать.
А данные по индексу уже будут выдаваться отсортированные.

Несколько страшно, т.к. надо быть уверенным, что план запроса использует индекс.

Иначе, как уже говорили, надо бороться со скоростью сортировки больших
объемов данных.
16 мар 04, 11:58    [579881] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Animal
Member

Откуда:
Сообщений: 525
Правильно. При этом - на практике - TABLE FULL SCAN выдает записи согласно их расположению в блоках, то есть при вставке по порядку и отсутствии удалений в таком порядке и выдает

В корне не верное заблуждение.


Ты серьезно уверен, что table full scan в таком случае лучше, нежели index full scan? Обоснуешь? Для таблицы с 10.000.000 записей? Обратив внимание на first_rows?

То есть - даже при select * from ldr$invoices order by invoice_id сервер не пытается использовать индекс по invoice_id - что, имхо, крайне странно.

И где тут хоть одно слово про хинт?



ЗЫ
На счет обоснования. Прям сейчас у меня нет времени, потому как мне ужо пора сваливать с работы по другим делам. Завтра если будет время прикину чё как.
16 мар 04, 12:07    [579912] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
Хм. Он написан в исходном сообщении
Еще раз просмотрел, так и не увидел

Видимо, мы с тобой как-то по разному понимаем его представление.

Для меня план - это последовательность шагов (операций), предпринимаемых движком, то есть в данном случае INDEX FULL SCAN / TABLE ACCESS BY INDEX ROWID / SORT ORDER BY. Оракл и всякие визуальные средства обычно представляют его в виде дерева, примерно так (если форматирование опять не поудаляет лишних пробелов)


SELECT STATEMENT
SORT ORDER BY
TABLE ACCESS BY INDEX ROWID LDR$INVOICES
INDEX FULL SCAN LDR$INVOICES_PK

Это - план для запроса с хинтом индекса. Без него первые два шага (index full scan и table access by index rowid) заменяются одним table full scan
16 мар 04, 12:07    [579913] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Barkovsky
Member

Откуда: Санкт-Петербург
Сообщений: 2515
если invoice_id - это первичный ключ включите RBO

select * /*+RULE*/ 

from ldr$invoices
where invoice_id > :start_invoice_id
order by invoice_id


то для RBO план должен быть таким:

SELECT STATEMENT, GOAL = CHOOSE				

TABLE ACCESS BY INDEX ROWID ldr$invoices REPLICATION
INDEX RANGE SCAN UNIQUE invoice_id_PK my_schema


лишняя сортировка при этом не производится, данные выбираются прямо из индекса.
проверьте.
16 мар 04, 12:10    [579919] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
e
Есть не совсем корректное предложение.
Убрать ORDER BY.

Есть такое. Но это имхо - для админских скриптов, того, что выполняется руками и может быть проконтролировано. Мне страшновато будет отдавать в эксплуатацию систему с таким хаком, который может слететь в любой момент - например, sql*loader при неудачном завершении может оставить индекс в unusable state, и я не уверен, что в этом случае попытка чтения данных ругнется, а не просто наплюет на этот индекс и пойдет давать записи в случайном порядке.

Правильно. При этом - на практике - TABLE FULL SCAN выдает записи согласно их расположению в блоках, то есть при вставке по порядку и отсутствии удалений в таком порядке и выдает
В корне не верное заблуждение.

Это - практика. Естественно, на нее нельзя полагаться в решениях, но для наблюдений имхо годится. Если, конечно, помнить о границах применимости - в частности о том, что при параллельной вставке из разных сессий это соображение можно выкидывать на помойку.
16 мар 04, 12:17    [579944] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
если invoice_id - это первичный ключ включите RBO

то для RBO план должен быть таким:
SELECT 

TABLE ACCESS BY INDEX ROWID
INDEX RANGE SCAN


Это было бы то, что надо. Увы. У меня почему-то TABLE FULL SCAN / SORT ORDER BY во всех без исключения режимах оптимизатора. Я полагаю, дело в настройках сервера, но я не админ и не знаю, чем можно поиграть.
16 мар 04, 12:22    [579962] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Barkovsky
Member

Откуда: Санкт-Петербург
Сообщений: 2515
я просто покажу, что это возможно.
покажите, что у вас возвращате тестовый пример.

SQL*Plus: Release 8.1.7.0.0 - Production on Tue Mar 16 12:57:07 2004


(c) Copyright 2000 Oracle Corporation. All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production

SQL> set autotrace on exp

SQL> drop table test_tbl
2 /

Table dropped.

SQL> create table test_tbl(id number, name varchar2(10))
2 /

Table created.

SQL> alter table test_tbl add primary key(id)
2 /

Table altered.

SQL> select /*+RULE*/* from test_tbl
2 where id>1
3 order by id
4 /

no rows selected


Execution Plan
----------------------------------------------------------

0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TBL'
2 1 INDEX (RANGE SCAN) OF 'SYS_C007897' (UNIQUE)



SQL>
16 мар 04, 12:47    [580077] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Scott Tiger
Member

Откуда: Солнышко
Сообщений: 6093
2 softwarer - может, у тебя индекса нет?
16 мар 04, 12:50    [580086] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Barkovsky
Member

Откуда: Санкт-Петербург
Сообщений: 2515
кстати, я такой артефакт встречал:) первичный ключ, без индекса.
после импорта родилось такое. редкий баг:)
16 мар 04, 12:55    [580108] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
2 softwarer - может, у тебя индекса нет?


Тогда хинт на использование индекса игнорировался бы, не меняя план запроса.

Есть, все есть. И индекс, и первичный ключ, и таблица. И план не как у людей :-)
16 мар 04, 12:57    [580112] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
я просто покажу, что это возможно.

Я в этом не сомневался :-)

покажите, что у вас возвращате тестовый пример.

Как ни странно, то же самое. "Мой" эффект наблюдается на двух таблицах (5 и 10 миллионов записей), закачанных sql*loader'ом; как я сейчас проверил, на таблицах, сделанных с них create as select (без данных) все работает как надо.

Что ж, большое спасибо за наводку. Сам как-то не додумался создать таблицу для эксперимента. Сейчас попробую пересоздать первичный ключ; по результатам - напишу.

(P.S. Для особо зубастых :-). Есть индекс - есть в dba_indexes, state = 'VALID', при попытке дропнуть оракл говорит, что индекс используется для первичного ключа)
16 мар 04, 13:13    [580184] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Я и ёжик
Member

Откуда: СПб
Сообщений: 1511
автор
Стартовое значение для начала принимает id'шник последней обработанной записи; чтобы не попасть в shapshot too old, запрос время от времени переоткрывается с новым стартовым id-шником.

1) Т.е. вы сначала просите Oracle вернуть один объем записей, а потом получив значительно меньший, его прерываете и начинаете всё опять?
Ну вы бы сказали ему сразу давай мне, типа, ключи в диапазоне с/по, я думаю оптимизатору было бы намного проще Вас понять...
select * 

from ldr$invoices
where invoice_id > :start_invoice_id and invoice_id <= :start_invoice_id + STEP_VALUE


2) У вашего индекса по PK степень кластиризации явно низкая ( записи не упорядочены по ключу ) в такой ситуации в теории количество физических чтений блоков принято оценивать равным числу выбираемых из индекса строк ( взяв из индекса id нужной строки за блоком приходится лезть на диск, поскольку прошлый раз мы за этим блоком лазали давно и сами же могли его уже вытеснить из кэша) и блоки при этом из базовой таблицы читаются по одному.
В Вашем (показаном) запросе используется Bind переменная, т.е. на этапе построения запроса оптимизатор не в состоянии оценить объем выбираемого диапазона, опять же в теории в таких случаях оценку берут как 1/3 от общего объема записей. Итого при Index Range Scan оптимизатор вправе ожидать, что для выполнения запроса потребуется физическое чтение ( 10 000 000 * 1/3 ) ~ 3 333 333 блоков.
При Full Table Scan потребуется 10 000 000 / (среднне число строк в блоке) операций физического чтения. Если предположить , что в блок у вас влезает в среднем, ну допустим 100 записей, то в этом случае для Table Full Scan потребуется всего 100 000 физических чтений, да еще и разделить на *_multibloks_read_count . Плюс сортировка, допустим в два прохода ну плюс еще 200 000 чтений, всё равно это на порядок меньше чем при применение Range Index Scan.

Так, что оптимизатор абсолютно прав, в том виде как вы даете ему запрос и при вашем распределении данных его надо выполнять именно с Table Full Scan,
а знать что вы где то там его прервете получив маленький кусочек данных он никак не может.

То же самое происходит когда вы пытаетесь хинтом заставить его использовать индекс, он его использует, но так как по его мнению будет эффективнее.

Помоему единственный нормальный выход, это показать сразу что вы обрабатываете только ограниченный сверху и снизу "косочек" данных, как я показал выше. Ну может еще вместо Bind переменных использовать константы и формировать запросы динамически, Shared пул думаю сильно не пострадает, тут же идет какаянибуть единичная ночная обработка, хотя думаю и без того оптимизатор пойдет по индексу.

Успехов!
16 мар 04, 13:19    [580205] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Barkovsky
Member

Откуда: Санкт-Петербург
Сообщений: 2515
Я и ёжик
У вашего индекса по PK степень кластиризации явно низкая ( записи не упорядочены по ключу ) в такой

то есть это столбец clustering_factor в dba_indexes?

а где-нибудь можно почитать подробней об этом?
16 мар 04, 13:31    [580260] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
Что ж, пересоздание индекса (точнее, первичного ключа) помогло. Собственно, после этого правильный план строить не только при rule, но и при любых других режимах оптимизатора. Еще раз спасибо уважаемому Barkovsky за правильный подход к эксперименту.

Стартовое значение для начала принимает id'шник последней обработанной записи; чтобы не попасть в shapshot too old, запрос время от времени переоткрывается с новым стартовым id-шником.

1) Т.е. вы сначала просите Oracle вернуть один объем записей, а потом получив значительно меньший, его прерываете и начинаете всё опять?
Ну вы бы сказали ему сразу давай мне, типа, ключи в диапазоне с/по, я думаю оптимизатору было бы намного проще Вас понять...

В данном случае это не должно быть существенно - посколько сервер все равно подгружает данные по мере необходимости. С другой стороны, я не хочу закладываться на то, что id'шники выданы плотно и без перерывов - а в этом случае как минимум придется предпринимать дополнительные усилия, чтобы понять, означают ли 0 записей в очередном курсоре окончание полной выборки или же просто попадание в дыру нумерации.

У вашего индекса по PK степень кластиризации явно низкая ( записи не упорядочены по ключу ) в такой ситуации в теории количество физических

Не поделитесь, почему Вы так предположили (не как наезд - мне интересно, что учитывает человек, знающий больше меня)?

Изначальный индекс я, к сожалению дропнул; у аналогичной, точно так же закачанной таблицы поле clustering_factor содержит значение 5048900 - полагаю, это высокий фактор? Видимо, sql*loader хорошо отрабатывает этот вопрос.

При Full Table Scan потребуется 10 000 000 / (среднне число строк в блоке) операций физического чтения. Если предположить , что в блок у вас
..................................
Так, что оптимизатор абсолютно прав, в том виде как вы даете ему запрос и при вашем распределении данных его надо выполнять именно с Table Full Scan,

А сортировка никак не влияет на эту математику? Имхо оптимизатор должен учитывать, что при использовании индекса ему не придется дополнительно сортировать порядка 3 333 333 записей. Что по идее особенно важно на first_rows, при котором план запроса также не менялся.
16 мар 04, 13:51    [580333] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
Ну может еще вместо Bind переменных использовать константы и формировать запросы динамически, Shared пул думаю сильно не пострадает, тут же идет какаянибуть единичная ночная обработка, хотя думаю и без того оптимизатор пойдет по индексу

Если не ошибаюсь, в этом случае придется засовывать в динамический sql и код обработки, что как минимум приведет к необходимости публиковать в пакете подпрограмму обработки полученных строк и к постоянному переключению режима работы.

Или если возможность присвоить динамический sql нормальному статическому курсору?
16 мар 04, 14:06    [580384] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Urri
Member

Откуда: Москва
Сообщений: 2603
По-моему, достаточно переписать запрос так, чтобы ограничить диапазон выбираемых invoice_id с двух сторон. Причем сознательно выбрать небольшой диапазон. Потом собрать статистику. И посмотреть, что тогда будет с планом запроса.
16 мар 04, 14:22    [580433] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
Я и ёжик
Member

Откуда: СПб
Сообщений: 1511
Barkovsky
автор
то есть это столбец clustering_factor в dba_indexes?

Да, если значение clustering_factor близко к числу блоков в таблице, то таблица сильно упорядочена по данному индексу, если близко к числу строк в таблице, то наоборот , абсолютно дизорганизована по индексу.
автор

а где-нибудь можно почитать подробней об этом?


У Кайта в 1 книге, в главе про индексы он рассматривает пример кластеризованного и не кластеризованнного индекса и как это влияет на число чтений. Кажется в разделе "почему не используется индекс?", хотя могу ошибаться, но в главе про индексы точно.

softwarer
автор

Не поделитесь, почему Вы так предположили (не как наезд - мне интересно, что учитывает человек, знающий больше меня)?

Если про низкий фактор кластеризации, то исключительно по Вашим словам:" если сделать просто select * from ldr$invoices, первая порция возвращается мгновенно, но в довольно странном порядке... <и далее пример>" и потому что оптимизатор упорно игнорирует Index Range Scan. Это конечно не строгое обоснование, но уж больно ситуация подходит под этот случай. Т.е. я просто предположил :). А вообще как определить степень кластеризации написал выше.

Если про число физических чтений , то по любому учебнику, например:
Гектор Гарсиа-Молина, Джеффри Ульман, Дженнифер Уидом "Системы баз данных. Полный курс".


автор
А сортировка никак не влияет на эту математику? Имхо оптимизатор должен учитывать, что при использовании индекса ему не придется дополнительно сортировать порядка 3 333 333 записей. Что по идее особенно важно на first_rows, при котором план запроса также не менялся.

Я выше писал, что сортировать 100 тысяч блоков (а даже не 100 тысяч а 33 тысячи) значительно дешевле чем считывать 3 миллона БЛОКОВ ( число чтений блоков базовой таблиы при scan-е по не кластеризованному индексу близко к общему числу строк просмотренных в индексе, т.е. найдя Rowid строки в индексе за нужным блоком приходится лезть на диск т.к. очень велика вероятность , что из кеша он уже ушел).

автор
Что ж, пересоздание индекса (точнее, первичного ключа) помогло.
А вот это уже сводит все мои рассуждения к нулю. Пересоздание дерева может его "выпрямить" но никак не изменить фактор кластеризации таблицы по ключу. Я правильно понял, что ппервичный ключь был просто дропнут и пересоздан? А статистика была после этого собрана, может оптимизатор просто больше не знает что индекс такой хреновый?;)

автор
Или если возможность присвоить динамический sql нормальному статическому курсору?

REF CURSOR и open for - fetch- close
16 мар 04, 14:46    [580514] Ответить | Цитировать    Сообщить модератору

 Re: Oracle9i: плохо выполняется простой запрос   [new]
softwarer
Member

Откуда: Москва
Сообщений: 24460
автор
По-моему, достаточно переписать запрос так, чтобы ограничить диапазон выбираемых invoice_id с двух сторон. Причем сознательно выбрать небольшой диапазон. Потом собрать статистику. И посмотреть, что тогда будет с планом запроса.

До тех пор, пока мы используем pl/sql-курсоры, запрос ... where id > :b1 вряд ли отличается для оптимизатора от запроса ... where id between :b1 and :b2. Потому как в обоих случаях у него нет способа на этапе парсинга предсказать селективность.
16 мар 04, 14:48    [580524] Ответить | Цитировать    Сообщить модератору

Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить
Generated time: 375ms.
Rambler's Top100 Powered by ActualForum 1.5.3 [s1] Copyright (c) Alex Sibilev 2000-2010