вложенный где существует занимает слишком много времени для выполнения - PullRequest
0 голосов
/ 27 мая 2019

У меня следующий запрос, который работает нормально и не занимает много времени

назовем это запросом 1:

select t3.date2
      ,t4.date1
      ,case
          when t4.date1 is null then
           t3.date2
          else
           t4.date1
       end check_date
      ,t3.dimension2
  from (select max(date2) date2
              ,dimension2
          from view1 t4
         where measure2 > 0
         group by dimension2) t3
  left join (select max(t1.date1) date1
                   ,t1.dimension1
               from table1 t1
              where dimension2 = 'some value'
                and exists (select 1
                       from (select max(date2) date2
                                   ,dimension2
                               from view1
                              where measure2 > 0
                              group by dimension2) t2
                      where t1.date1 > t2.date2
                        and t1.dimension1 = t2.dimension2)
              group by t1.dimension1) t4
    on t3.dimension1 = t4.dimension1;

EXPLAIN PLAN FOR ABOVE QUERY:
-----------------------------------------------------------------------
| Id  | Operation                           | Name                    |
-----------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                         |
|   1 |  HASH JOIN RIGHT OUTER              |                         |
|   2 |   VIEW                              |                         |
|   3 |    HASH GROUP BY                    |                         |
|   4 |     HASH JOIN RIGHT SEMI            |                         |
|   5 |      VIEW                           |                         |
|   6 |       HASH GROUP BY                 |                         |
|   7 |        HASH JOIN RIGHT OUTER        |                         |
|   8 |         INDEX STORAGE FAST FULL SCAN| TABLEB                  |
|   9 |         HASH JOIN RIGHT OUTER       |                         |
|  10 |          TABLE ACCESS STORAGE FULL  | TABLEA                  |
|  11 |          TABLE ACCESS STORAGE FULL  | VIEW1                   |
|  12 |      TABLE ACCESS STORAGE FULL      | TABLE1                  |
|  13 |   VIEW                              |                         |
|  14 |    HASH GROUP BY                    |                         |
|  15 |     HASH JOIN RIGHT OUTER           |                         |
|  16 |      INDEX STORAGE FAST FULL SCAN   | TABLEB                  |
|  17 |      HASH JOIN RIGHT OUTER          |                         |
|  18 |       TABLE ACCESS STORAGE FULL     | TABLEA                  |
|  19 |       TABLE ACCESS STORAGE FULL     | VIEW1                   |
-----------------------------------------------------------------------

Теперь, используя предыдущий запрос 1, я создаю новый запрос. Этот запрос не выдает никакой ошибки, но для запуска * 1006 требуется вечность

select a
      ,b
      ,date1
      ,dimension
  from table1 t5
 where some_condition = 'some condition'
   and some_column is null
   and exists (select 1
          from ('query 1 here') t6
         where t5.dimension = t6.dimension2
           and t5.date1 >= t6.check_date);

EXPLAIN PLAN FOR ABOVE QUERY:
-----------------------------------------------------------------------------
| Id  | Operation                                 | Name                    |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT                          |                         |
|   1 |  FILTER                                   |                         |
|   2 |   INLIST ITERATOR                         |                         |
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED    | TABLE1                  |
|   4 |     INDEX RANGE SCAN                      | TABLEC                  |
|   5 |   FILTER                                  |                         |
|   6 |    NESTED LOOPS OUTER                     |                         |
|   7 |     VIEW                                  |                         |
|   8 |      SORT GROUP BY                        |                         |
|   9 |       HASH JOIN OUTER                     |                         |
|  10 |        HASH JOIN OUTER                    |                         |
|  11 |         TABLE ACCESS STORAGE FULL         | VIEW1                   |
|  12 |         TABLE ACCESS STORAGE FULL         | TABLEA                  |
|  13 |        INDEX STORAGE FAST FULL SCAN       | TABLEB                  |
|  14 |     VIEW                                  |                         |
|  15 |      SORT GROUP BY                        |                         |
|  16 |       HASH JOIN SEMI                      |                         |
|  17 |        TABLE ACCESS BY INDEX ROWID BATCHED| TABLE1                  |
|  18 |         INDEX RANGE SCAN                  | TABLE1_N5               |
|  19 |        VIEW                               |                         |
|  20 |         SORT GROUP BY                     |                         |
|  21 |          HASH JOIN OUTER                  |                         |
|  22 |           HASH JOIN OUTER                 |                         |
|  23 |            TABLE ACCESS STORAGE FULL      | VIEW1                   |
|  24 |            TABLE ACCESS STORAGE FULL      | TABLEA                  |
|  25 |           INDEX STORAGE FAST FULL SCAN    | TABLEB                  |
-----------------------------------------------------------------------------

У меня также такой же запрос, как и выше, но вместо части «запрос 1 здесь» у меня есть гораздо более простой запрос, например «выбрать максимум (некоторая дата), dim из t group by dim», который возвращает намного больше данных (я я уверен в этом), но он работает быстро и дает мне результат, но при объединении в приведенном выше запросе он работает вечно, и мне приходится вручную завершать его

** Я не являюсь разработчиком Oracle / SQL, я просто использую запрос select для извлечения данных, и иногда, когда возвращаемые данные слишком велики, я пытаюсь преобразовать их непосредственно в запрос, чтобы избежать постобработки

...