Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как оптимизировать запрос 
:(
    Опции темы
Elnarka
Дата 29.4.2008, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 13.2.2008

Репутация: нет
Всего: нет



Здравствуйте.У меня есть вот такой запрос:
Код

select cc.id_account,tt.id_contracts,sum(tt.val) val
from 
(
select distinct c.id_contracts ,pr.saldoprcmain as val
  from 
       dwh.fct_charge_prc    pr,
       dwh.con_ass_contr_acc con,
       dwh.det_contracts c ,
       dwh.con_ass_acc       ac,
       dwh.det_ord_liab      l,
       dwh.det_source sr
       
       
 where
   ac.id_account_parent = 11398446
   and '20.04.2008' BETWEEN ac.dt_open and ac.dt_close
   and con.id_account = ac.id_account_parent
   and '20.04.2008' BETWEEN con.dt_open and con.dt_close
   and con.id_tacc = 61282
   and c.id_contracts = con.id_contracts 
   and (('20.04.2008' between c.date_open and c.date_closed)
        or c.date_closed is null)
   and c.id_source = sr.id_source
   and sr.code_source = 'Loans'
   and pr.id_contracts = c.id_contracts 
   AND '20.04.2008' BETWEEN pr.DT_OPEN AND pr.DT_CLOSE
   and l.id_ord_liab = pr.id_ord_liab
   and l.code_ord_liab like '%fl%'
)tt 
join 
dwh.con_ass_contr_acc cc
on  
tt.id_contracts = cc.id_contracts
where 
'20.04.2008' between cc.dt_open and cc.dt_close

group by cc.id_account,tt.id_contracts


Никак не выполняется. 
План таков.

Код

SELECT STATEMENT, GOAL = ALL_ROWS            Cost=506    Cardinality=81    Bytes=3807
 SORT GROUP BY                  Cost=506     Cardinality=81                   Bytes=3807
  TABLE ACCESS BY INDEX ROWID          bject name=CON_ASS_CONTR_ACC    Cost=363    Cardinality=81    Bytes=2268
   NESTED LOOPS            Cost=504    Cardinality=81    Bytes=3807
    VIEW    Object owner=ELNARA        Cost=141    Cardinality=1    Bytes=19
     SORT UNIQUE            Cost=141    Cardinality=1    Bytes=172
      MERGE JOIN CARTESIAN            Cost=139    Cardinality=23    Bytes=3956
       NESTED LOOPS            Cost=11    Cardinality=1    Bytes=150
        NESTED LOOPS            Cost=9    Cardinality=1    Bytes=131
         NESTED LOOPS            Cost=7    Cardinality=1    Bytes=74
          NESTED LOOPS            Cost=6    Cardinality=1    Bytes=61
           TABLE ACCESS BY INDEX ROWID        Object name=CON_ASS_CONTR_ACC    Cost=5    Cardinality=1    Bytes=33
            INDEX RANGE SCAN                  Object name=AK_ASS_CONTR    Cost=3    Cardinality=1    
           TABLE ACCESS BY INDEX ROWID        Object name=DET_CONTRACTS    Cost=1    Cardinality=1    Bytes=28
            INDEX UNIQUE SCAN        Object name=PK_DET_CONTRACTS        Cardinality=1    
          TABLE ACCESS BY INDEX ROWID        Object name=DET_SOURCE    Cost=1    Cardinality=1    Bytes=13
           INDEX UNIQUE SCAN        Object name=PK_DET_SOURCE        Cardinality=1    
         TABLE ACCESS BY GLOBAL INDEX ROWID        Object name=FCT_CHARGE_PRC    Cost=2    Cardinality=1    Bytes=57
          INDEX RANGE SCAN    Object name=AK_CHARGE_PRC_FCT_CHAR    Cost=1    Cardinality=15    
        TABLE ACCESS BY INDEX ROWID        Object name=DET_ORD_LIAB    Cost=2    Cardinality=1    Bytes=19
         INDEX UNIQUE SCAN        Object name=PK_DET_ORD_LIAB    Cost=1    Cardinality=1    
       BUFFER SORT            Cost=137    Cardinality=215    Bytes=4730
        TABLE ACCESS BY INDEX ROWID        Object name=CON_ASS_ACC    Cost=128    Cardinality=215    Bytes=4730
         INDEX RANGE SCAN        Object name=RELATION_11401_FK    Cost=2    Cardinality=215    
    INDEX RANGE SCAN        Object name=RELATION_11430_FK    Cost=2    Cardinality=81    


Вобще.Где можно получить хорошую информацию про оптимизацию?Несовсем понимаю 
PM MAIL   Вверх
DimW
Дата 29.4.2008, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



1) дайте информацию о количестве строк в каждой из таблиц:
dwh.fct_charge_prc   
dwh.con_ass_contr_acc
dwh.det_contracts    
dwh.con_ass_acc      
dwh.det_ord_liab     
dwh.det_source   

2) сколько строк возвращает этот селест:
Код

select distinct c.id_contracts
                       ,pr.saldoprcmain as val
          from dwh.fct_charge_prc    pr
              ,dwh.con_ass_contr_acc con
              ,dwh.det_contracts     c
              ,dwh.con_ass_acc       ac
              ,dwh.det_ord_liab      l
              ,dwh.det_source        sr
        
         where ac.id_account_parent = 11398446
           and '20.04.2008' BETWEEN ac.dt_open and ac.dt_close
           and con.id_account = ac.id_account_parent
           and '20.04.2008' BETWEEN con.dt_open and con.dt_close
           and con.id_tacc = 61282
           and c.id_contracts = con.id_contracts
           and (('20.04.2008' between c.date_open and c.date_closed) or c.date_closed is null)
           and c.id_source = sr.id_source
           and sr.code_source = 'Loans'
           and pr.id_contracts = c.id_contracts
           AND '20.04.2008' BETWEEN pr.DT_OPEN AND pr.DT_CLOSE
           and l.id_ord_liab = pr.id_ord_liab
           and l.code_ord_liab like '%fl%'
 

3) вы принципиально используете ansi синтаксис (join)? можно увидеть план запроса без использования join?!    



Это сообщение отредактировал(а) DimW - 29.4.2008, 09:32
PM MAIL ICQ   Вверх
Elnarka
Дата 29.4.2008, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 13.2.2008

Репутация: нет
Всего: нет



dwh.fct_charge_prc    - около 4 млн 
dwh.con_ass_contr_acc - около 4 млн 
dwh.det_contracts    - 2 млн
dwh.con_ass_acc    - 4 млн
dwh.det_ord_liab     - 1 млн
dwh.det_source   - 100 записей




Запрос возврашает около 2000 записей


Без использования join 
Код

SELECT STATEMENT, GOAL = CHOOSE            Cost=508    Cardinality=74    Bytes=2516
 SORT GROUP BY            Cost=508    Cardinality=74    Bytes=2516
  VIEW    Object owner=SYS        Cost=508    Cardinality=74    Bytes=2516
   SORT UNIQUE            Cost=508    Cardinality=74    Bytes=16650
    MERGE JOIN CARTESIAN            Cost=504    Cardinality=74    Bytes=16650
     NESTED LOOPS            Cost=376    Cardinality=1    Bytes=203
      NESTED LOOPS            Cost=374    Cardinality=1    Bytes=190
       NESTED LOOPS            Cost=11    Cardinality=1    Bytes=150
        NESTED LOOPS            Cost=9    Cardinality=1    Bytes=131
         NESTED LOOPS            Cost=7    Cardinality=1    Bytes=74
          NESTED LOOPS            Cost=6    Cardinality=1    Bytes=61
           TABLE ACCESS BY INDEX ROWID        Object name=CON_ASS_CONTR_ACC    Cost=5    Cardinality=1    Bytes=33
            INDEX RANGE SCAN        Object name=AK_ASS_CONTR    Cost=3    Cardinality=1    
           TABLE ACCESS BY INDEX ROWID        Object name=DET_CONTRACTS    Cost=1    Cardinality=1    Bytes=28
            INDEX UNIQUE SCAN        Object name=PK_DET_CONTRACTS        Cardinality=1    
          TABLE ACCESS BY INDEX ROWID    Object name=DET_SOURCE    Cost=1    Cardinality=1    Bytes=13
           INDEX UNIQUE SCAN                    Object name=PK_DET_SOURCE        Cardinality=1    
         TABLE ACCESS BY GLOBAL INDEX ROWID        Object name=FCT_CHARGE_PRC    Cost=2    Cardinality=1    Bytes=57
          INDEX RANGE SCAN    Object name=AK_CHARGE_PRC_FCT_CHAR    Cost=1    Cardinality=15    
        TABLE ACCESS BY INDEX ROWID        Object name=DET_ORD_LIAB    Cost=2    Cardinality=1    Bytes=19
         INDEX UNIQUE SCAN        Object name=PK_DET_ORD_LIAB    Cost=1    Cardinality=1    
       TABLE ACCESS BY INDEX ROWID    Object name=CON_ASS_CONTR_ACC    Cost=363    Cardinality=3    Bytes=120
        INDEX RANGE SCAN        Object name=RELATION_11430_FK    Cost=2    Cardinality=81    
      TABLE ACCESS BY INDEX ROWID        Object name=DET_ACCOUNT    Cost=2    Cardinality=1    Bytes=13
       INDEX UNIQUE SCAN    Object name=PK_DET_ACCOUNT    Cost=1    Cardinality=1    
     BUFFER SORT            Cost=502    Cardinality=215    Bytes=4730
      TABLE ACCESS BY INDEX ROWID    Object name=CON_ASS_ACC    Cost=128    Cardinality=215    Bytes=4730
       INDEX RANGE SCAN        Object name=RELATION_11401_FK    Cost=2    Cardinality=215


Добавлено @ 10:12
Запрос соответствующий последнему плану таков

Код

select a.id_account, tt.id_contracts,sum(val) val
from dwh.con_ass_contr_acc cc,dwh.det_account a,
   
(
select distinct c.id_contracts ,pr.saldoprcmain as val
  from 
       dwh.fct_charge_prc    pr,
       dwh.con_ass_contr_acc con,
       dwh.det_contracts c ,
       dwh.con_ass_acc       ac,
       dwh.det_ord_liab      l,
       dwh.det_source sr
       
       
 where
   ac.id_account_parent = 11398446
   and '20.04.2008' BETWEEN ac.dt_open and ac.dt_close
   and con.id_account = ac.id_account_parent
   and '20.04.2008' BETWEEN con.dt_open and con.dt_close
   and con.id_tacc = 61282
   and c.id_contracts = con.id_contracts 
   and (('20.04.2008' between c.date_open and c.date_closed)
        or c.date_closed is null)
   and c.id_source = sr.id_source
   and sr.code_source = 'Loans'
   and pr.id_contracts = c.id_contracts 
   AND '20.04.2008' BETWEEN pr.DT_OPEN AND pr.DT_CLOSE
   and l.id_ord_liab = pr.id_ord_liab
   and l.code_ord_liab like '%fl%' ) tt 

   where cc.id_contracts = tt.id_contracts
   and '20.04.2008' between cc.dt_open and cc.dt_close
   and cc.id_tacc = 61282
   and cc.id_account =a.id_account  
   and a.is_gk = 0
   
   group by  a.id_account, tt.id_contracts

PM MAIL   Вверх
DimW
Дата 29.4.2008, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Elnarka, покажи план этого запроса:
Код

select count(*)
  from dwh.fct_charge_prc    pr
      ,dwh.con_ass_contr_acc con
      ,dwh.det_contracts     c
      ,dwh.con_ass_acc       ac
      ,dwh.det_ord_liab      l
      ,dwh.det_source        sr
 where ac.id_account_parent = 11398446
   and to_date('20.04.2008', 'dd.mm.yyyy') BETWEEN ac.dt_open and ac.dt_close
   and con.id_account = ac.id_account_parent
   and to_date('20.04.2008', 'dd.mm.yyyy') BETWEEN con.dt_open and con.dt_close
   and con.id_tacc = 61282
   and c.id_contracts = con.id_contracts
   and ((to_date('20.04.2008', 'dd.mm.yyyy') between c.date_open and c.date_closed) or
       c.date_closed is null)
   and c.id_source = sr.id_source
   and sr.code_source = 'Loans'
   and pr.id_contracts = c.id_contracts
   AND to_date('20.04.2008', 'dd.mm.yyyy') BETWEEN pr.DT_OPEN AND pr.DT_CLOSE
   and l.id_ord_liab = pr.id_ord_liab
   and l.code_ord_liab like '%fl%'

именно этого!

и за какое время он выполняется?
есть подозрение что во всем виноват distinct  который приводит к сортировке подселекта.

Добавлено через 5 минут и 34 секунды
да и трассировку посмотреть бы не мешало. возможно слишком много дисковых чтений.
PM MAIL ICQ   Вверх
Elnarka
Дата 29.4.2008, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 13.2.2008

Репутация: нет
Всего: нет



План вашего запроса таков

SELECT STATEMENT, GOAL = CHOOSE            Cost=139    Cardinality=1    Bytes=159
 SORT AGGREGATE                Cardinality=1    Bytes=159
  MERGE JOIN CARTESIAN            Cost=139    Cardinality=23    Bytes=3657
   NESTED LOOPS            Cost=11    Cardinality=1    Bytes=137
    NESTED LOOPS            Cost=9    Cardinality=1    Bytes=118
     NESTED LOOPS            Cost=7    Cardinality=1    Bytes=74
      NESTED LOOPS            Cost=6    Cardinality=1    Bytes=61
       TABLE ACCESS BY INDEX ROWID    Object name=CON_ASS_CONTR_ACC    Cost=5    Cardinality=1    Bytes=33
        INDEX RANGE SCAN        Object name=AK_ASS_CONTR    Cost=3    Cardinality=1    
       TABLE ACCESS BY INDEX ROWID    Object owner=DWH    Object name=DET_CONTRACTS    Cost=1    Cardinality=1    Bytes=28
        INDEX UNIQUE SCAN    Object name=PK_DET_CONTRACTS        Cardinality=1    
      TABLE ACCESS BY INDEX ROWID    Object name=DET_SOURCE    Cost=1    Cardinality=1    Bytes=13
       INDEX UNIQUE SCAN    Object name=PK_DET_SOURCE        Cardinality=1    
     TABLE ACCESS BY GLOBAL INDEX ROWID    Object name=FCT_CHARGE_PRC    Cost=2    Cardinality=1    Bytes=44
      INDEX RANGE SCAN        Object name=AK_CHARGE_PRC_FCT_CHAR    Cost=1    Cardinality=15    
    TABLE ACCESS BY INDEX ROWID        Object name=DET_ORD_LIAB    Cost=2    Cardinality=1    Bytes=19
     INDEX UNIQUE SCAN        Object name=PK_DET_ORD_LIAB    Cost=1    Cardinality=1    
   BUFFER SORT            Cost=137    Cardinality=215    Bytes=4730
    TABLE ACCESS BY INDEX ROWID        Object name=CON_ASS_ACC    Cost=128    Cardinality=215    Bytes=4730
     INDEX RANGE SCAN        Object name=RELATION_11401_FK    Cost=2    Cardinality=215    


выполнился за 1810.953 ыулгтв



Извините(простите за такой вопрос),а как трассировку посмотреть? )) 


PM MAIL   Вверх
DimW
Дата 29.4.2008, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Цитата(Elnarka @  29.4.2008,  12:39 Найти цитируемый пост)
выполнился за 1810.953 ыулгтв

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

Цитата(Elnarka @  29.4.2008,  12:39 Найти цитируемый пост)
а как трассировку посмотреть?

попытаюсь объяснить.

все действия делаются в одной сесии!
1) включаем трассировку:
Код

alter session set events '10046 trace name context forever, level 12';


2) выполняешь свой запрос, и ждешь окончания результата.
3) выполняешь след. запрос чтобы получить путь и имя твоего файла с тарссировкой: 
Код

select rtrim(c.value, '/') || '/' || d.instance_name || '_ora_' || ltrim(to_char(a.spid)) || '.trc'
  from sys.v_$process a
      ,sys.v_$session b
      ,sys.v_$parameter c
      ,sys.v_$instance d
 where a.addr = b.paddr
   and b.audsid = sys_context('userenv', 'sessionid')
   and c.name = 'user_dump_dest';

это путь к файлу на сервере БД

4) закрываешь трассировку:
Код

alter session set events '10046 trace name context off';


и так ты получишь файл трассироки, но для его изучения необходимо еще предпринять пару шагов.
в ORACLE_HOME\BIN есть програмулина tkprof.exe при помощи нее можно получить читабельный файл оформив батник такова вида:
Код

tkprof <путь + имя трассировочного файла>.trc trc_report.prt


trc_report.prt это файлик который будет создан после выполнения этого батника.
его то и следует изучить.
надеюсь объяснил доходчиво.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.0944 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.