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

Есть Oracle 11.2.0.3, есть софтина, для которой вендор требует CURSOR_SHARING=FORCE на уровне системы.
Есть ряд запросов, для которых мне необходимо втыкнуть хинт CURSOR_SHARING_EXACT, ибо без него сильно страдает производительность.

Производительность страдает, т.к. Oracle не может устранить заведомо левые блоки из условий, вот пояснение:

alter session set cursor_sharing=force;

create table test_tab_1 tablespace users as 
select level as id, level as b, lpad(to_char(level),30,'x') as c
from dual connect by level<=10000;

create index test_ind_1 on test_tab_1 (id) tablespace users;


> select b 
from test_tab_1
where 
(id=100 ) or ('Alpha'='Bravo')
       100 

> select * from table(dbms_xplan.display_cursor('',''))
SQL_ID  fjyar27z2j3p0, child number 0                                            
-------------------------------------                                            
select b  from test_tab_1 where  (id=:"SYS_B_0" ) or                             
(:"SYS_B_1"=:"SYS_B_2")                                                          
                                                                                 
Plan hash value: 1943825358                                                      
                                                                                 
-------------------------------------------------------------------------------- 
| Id  | Operation         | Name       | Rows  | Bytes | Cost (%CPU)| Time     | 
-------------------------------------------------------------------------------- 
|   0 | SELECT STATEMENT  |            |       |       |    20 (100)|          | 
|*  1 |  TABLE ACCESS FULL| TEST_TAB_1 |     1 |    26 |    20   (0)| 00:00:01 | 
-------------------------------------------------------------------------------- 
                                                                                 
Predicate Information (identified by operation id):                              
---------------------------------------------------                              
                                                                                 
   1 - filter(("ID"=:SYS_B_0 OR :SYS_B_1=:SYS_B_2))                              
                                                                                 
Note                                                                             
-----                                                                            
   - dynamic sampling used for this statement (level=2)                          
                                                                                 

 23 rows selected 


> select /*+ CURSOR_SHARING_EXACT */ b 
from test_tab_1
where 
(id=100 ) or ('Alpha'='Bravo')
       100 

> select * from table(dbms_xplan.display_cursor('',''))
SQL_ID  0b208cpfujvsa, child number 0                                                                                    
-------------------------------------                                                                                    
select /*+ CURSOR_SHARING_EXACT */ b  from test_tab_1 where  (id=100 )                                                   
or ('Alpha'='Bravo')                                                                                                     
                                                                                                                         
Plan hash value: 49624373                                                                                                
                                                                                                                         
------------------------------------------------------------------------------------------                               
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |                               
------------------------------------------------------------------------------------------                               
|   0 | SELECT STATEMENT            |            |       |       |     2 (100)|          |                               
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST_TAB_1 |     1 |    26 |     2   (0)| 00:00:01 |                               
|*  2 |   INDEX RANGE SCAN          | TEST_IND_1 |     1 |       |     1   (0)| 00:00:01 |                               
------------------------------------------------------------------------------------------                               
                                                                                                                         
Predicate Information (identified by operation id):                                                                      
---------------------------------------------------                                                                      
                                                                                                                         
   2 - access("ID"=100)                                                                                                  
                                                                                                                         
Note                                                                                                                     
-----                                                                                                                    
   - dynamic sampling used for this statement (level=2)   


Т.е. часть "'Alpha'='Bravo'" сразу устраняется и мы можем ходить по индексу.

Вставить хинт в запрос "руками" нельзя - он генерируется приложением, запросов таких - сотни.
Пробовал через DBMS_SPM подсовывать CURSOR_SHARING_EXACT, INDEX и секцию OUTLINE_DATA - не подхватывается.
Есть еще какие-нибудь идеи?
27 фев 14, 10:31    [15637842]     Ответить | Цитировать Сообщить модератору
 Re: Поменять CURSOR_SHARING на уровне запроса  [new]
GuestA
Guest
Отвечу себе сам:

Поправить можно в данном конкретном случае так:
begin
for rec in (select SQL_FULLTEXT from v$sql where sql_id='fjyar27z2j3p0') loop
sys.dbms_sqldiag_internal.i_create_patch(
sql_text =>rec.sql_fulltext,
hint_text => 'USE_CONCAT(OR_PREDICATES(1))',
name => 'patch_fjyar27z2j3p0');
end loop;
end;
/
27 фев 14, 11:52    [15638532]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить