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

Добро пожаловать в форум, Guest  >>  Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик  Ответить
 Оптимизатор Oracle   [new]
lkv
Member

Откуда: Москва
Сообщений: 137
Случилось оптимизировать в-общем-то несложный запрос:
Непонятки: почему при использовании pipe функции в запросе в качестве базовой и ниличии PK в таблицах которые LEFT JOINятся к базовой оптимизатор ORACLE не может выбрать метод перебора INDEX UNIQUE SCAN?
Почему-то, он выбирает TABLE ACCESS FULL
SELECT /*+ ORDERED RULE */ B.NUM_1, B.NUM_2, B.SYS_NAME B_SYS_NAME, B.REST_TYPE, V.NAME as V_NAME, P.C_NAME, P.AMOUNT, P.BAL_SUMMA, P.BAL_DELTA, P.OFICDATE, P.RUR_RATE as RATE, P.USD_RATE,  P.VALUE_ID as "share", cast( dbo.f_Concat( V.NAME, dbo.f_Concat3( '(', P.C_NAME, ')' )) as varchar(255)) as NAME, V.SYSNAME, V.V_TYPE, I.NAME as I_NAME, I.BRANCHES, p15.DIAL_MODE as DM_15, p18.DIAL_MODE as DM_18, S.CLASS as S_CLASS, ST.TYPENAME as S_TYPE, S.NOMINAL, S.NOM_VAL, P.LEVEL_,
 dbo.iif_dd(P.AMOUNT,'=',0, 0, P.BAL_SUMMA/dbo.iif_dd(P.AMOUNT,'=',0, 1, P.AMOUNT)) as BAL_PRICE,
 dbo.iif_dd(P.AMOUNT,'=',0, 0, P.RUR_RATE/dbo.iif_dd(P.AMOUNT,'=',0, 1, P.AMOUNT)) as RUR_PRICE,
P.IS_MARKET_RATE
FROM  table(cast(PR_B_PORTFOLIO( 29739, NULL, '04.06.2004', 'F' ) as T_PR_B_PORTFOLIO)) P
left outer join OD_VALUES V on V.ID=P.VALUE_ID
left outer join FS_OD_BALANCES B on B.ID=P.BAL_ACC
left outer join FS_OD_SHARES S on S.ID=P.VALUE_ID
left outer join FS_OD_FACES I on I.SELF_ID=S.ISSUER and I.LAST_FLAG=1
left outer join OD_P_FACES p15 on p15.FACE=S.ISSUER and p15.DIAL_MODE=15 /*федерал*/
left outer join OD_P_FACES p18 on p18.FACE=S.ISSUER and p18.DIAL_MODE=18 /*муниципал*/
left join OD_SHARE_TYPES_VIEW ST on ST.CLASS=S.CLASS and ST.TYPE_=S.TYPE_
На вьюхе OD_SHARE_TYPES_VIEW и на таблице OD_P_FACES,
оптимизатор выбирает правильный метод перебора, а на OD_VALUES и FS_* полный перебот.
Join в этих таблицах 100% на UNIQUE primary?

Что-то я не разумею....

К сообщению приложен файл. Размер - 21Kb
23 июн 04, 16:32    [761040] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Alexey1
Member

Откуда:
Сообщений: 84
Таблицы маленькие, зачем смотреть еще индекс ??
23 июн 04, 17:08    [761176] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Ryaz
Member

Откуда: 62->99
Сообщений: 1308
http://oradba.com.ru/tuning/optimizer/articles/a2_srchintellcbo/contents.shtml

Может и поможет, написано очень хорошо.
23 июн 04, 17:13    [761192] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Markelenkov
Member

Откуда:
Сообщений: 2312
Вот кстати, хорошая новая статья от Джонатана:

http://otn.oracle.com/pub/articles/lewis_cbo.html
24 июн 04, 08:52    [761931] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
lkv
Member

Откуда: Москва
Сообщений: 137
2Alexey1:
Ищу причинну тормознутости:
Тем не менее Interbase7 обставляет Oracle на этом запросе просто в несколько раз. :(

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

Но ведь если не использовать stored procs такого не наблюдается!!! Я пробовал тестики с таблицам делать без подобного рода вызова SP/
Все же чики-пуки. Может у Oracle оптимизатора крышу сносит при виде
такого простого запроса или он корректно не умеет join к SP делать.

Или уж у меня руки не к тому месту..
24 июн 04, 18:56    [764264] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Markelenkov
Member

Откуда:
Сообщений: 2312
Попробуй выкинуть хинты, собрать статистику по всем объектам из запроса (желательно с гистограммами), собрать системную статистику.
24 июн 04, 19:18    [764291] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
killed
Member

Откуда: Moscow
Сообщений: 3189
Спасибо за ссылку. Интересная статья, прочел с удовольствием.
Вобщем, если человек говорит "я пишу оптимальные запросы" - не верьте, ему это только кажется
24 июн 04, 20:51    [764398] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Arthur Auhadeev
Member

Откуда: Казань
Сообщений: 132
Интербейс нельзя сравнивать с Ораклом, по умолчанию. ИБ хорош для крохотных баз, он, как и любая БД(СУБД) предназначен для своих (крохотных) задач. Как показывает практика, для крупных задач он не пригоден.
ИМХО.
25 июн 04, 00:20    [764480] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Alexey1
Member

Откуда:
Сообщений: 84
Только если уж собираешь статистику, то лучше переключиться на режим COST, а не RULE
25 июн 04, 09:34    [764722] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Я и ёжик
Member

Откуда: СПб
Сообщений: 1469
lkv
Но ведь если не использовать stored procs такого не наблюдается!!!


Если не использовать stored procs оптимизатор ( стоимостной) имеет статистику по используемой таблице и может примерно оценить объем возвращаемой информации, объем возвращаемой выборки из хранимой процедуры для него неизвестен, и он принимает его равным какому то своему внутреннему умолчальному значению ( это значение вероятно можно прикинуть посмотрев трассировку оптимизатора по event 10053), скорее всего он такой же как для непроанализированной таблицы, т.е. 100 блоков по 100 строк.

Начиная с 9i ( 9-ки нет проверить не могу) появился хинт CARDINALITY позволяющий указать число строк возвращаемых из таблицы, но он не в 9i не в 10g не документирован, по крайней мере я при беглом просмотре не нашел описания.

Пример на 10g.
Создаю нужные типы и функцию которая будет возвращать таблицу
Connected to:
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining options

SQL> create or replace type test_row as object ( p1 int, p2 int);
  2  /

Type created.

SQL> create or replace type test_table_type as table of test_row;
  2  /

Type created.

SQL> create or replace function test_func(p_rownum integer) return test_table_type is
  2    Result test_table_type;
  3  begin
  4    select test_row( object_id, object_id )
  5      bulk collect into Result
  6    from all_objects where rownum <= p_rownum;  
  7    return(Result);
  8  end test_func;
  9  /

Function created.
Создаю таблицу с которой буду соединять результат возвращаемый функцией:
SQL> create table test_table1 ( field1, field2) 
  2    as select  object_id, object_name from all_objects
  3  ;

Table created.

SQL> alter table test_table1 add primary key  (field1);

Table altered.

SQL> analyze table test_table1 compute statistics;

Table analyzed.
Теперь смотрим планчики, сначала без хинтов, оптимизатор не знает сколько строк вернется из функции:
SQL>  set autotrace traceonly exp
SQL> select t1.p1, t2.field2  
  2  from  table( cast( test_func(10) as test_table_type) )t1, test_table1 t2
  3  where t1.p1 = t2.field1;

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

0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=73 Card=8168 Bytes =253208) 1 0 HASH JOIN (Cost=73 Card=8168 Bytes=253208) 2 1 COLLECTION ITERATOR (PICKLER FETCH) OF 'TEST_FUNC' 3 1 TABLE ACCESS (FULL) OF 'TEST_TABLE1' (TABLE) (Cost=48 Ca rd=40285 Bytes=1168265)
Имеем FTS и HASH JOIN.

Теперь скажем оптимизатору, что ожидаем 10 строк:
SQL> select /*+ CARDINALITY( t1 10) */ t1.p1, t2.field2  
  2  from  table( cast( test_func(10) as test_table_type) )t1, test_table1 t2
  3  where t1.p1 = t2.field1;

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

0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=34 Card=10 Bytes=3 10) 1 0 NESTED LOOPS (Cost=34 Card=10 Bytes=310) 2 1 COLLECTION ITERATOR (PICKLER FETCH) OF 'TEST_FUNC' 3 1 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE1' (TABLE) ( Cost=1 Card=1 Bytes=29) 4 3 INDEX (UNIQUE SCAN) OF 'SYS_C005426' (INDEX (UNIQUE)) (Cost=0 Card=1)
INDEX UNIQUE SCAN и Nested loops.
25 июн 04, 11:17    [765073] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Markelenkov
Member

Откуда:
Сообщений: 2312
2 lkv

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

2 all

Бонус:

Список хинтов (включая недокументированные)
25 июн 04, 17:23    [766743] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Free Lancer
Guest
Markelenkov
Список хинтов (включая недокументированные)

А толку от такого списка, если для недокументированных нет никакого пояснения...
16 апр 08, 15:56    [5555976] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
Rihard
Member

Откуда: Киев
Сообщений: 369
Free Lancer
Markelenkov
Список хинтов (включая недокументированные)

А толку от такого списка, если для недокументированных нет никакого пояснения...

Для того, что бы ты знал, что такие существуют, и смог на досуге поисследовать их влияние на выполнение запроса.
P.S. Тынц =)
16 апр 08, 16:14    [5556149] Ответить | Цитировать    Сообщить модератору

 Re: Оптимизатор Oracle   [new]
_мухомор
Guest
Хинт CARDINALITY, даром что недокументированный, но самый простой и безобидный способ вправить мозги оптимизатору при применении PIPELINED функций.
Я получал несколько раз план запроса, где PIPELINED функция вынесена оптимизатором в Nested Loops наружу. Вот это была жесть.
16 апр 08, 16:41    [5556424] Ответить | Цитировать    Сообщить модератору

Все форумы / Oracle Ответить
Rambler's Top100 Powered by ActualForum 1.5.2 Copyright (c) Alex Sibilev 2000-2010