解决查询性能问题

Solving query performance issues

我一直遇到问题 knowing/understanding 如何优化以下查询,我对性能提示还很陌生,所以也许有人可以提供一些建议:

顺便说一句,我需要保留左侧 table (event_user) 的所有信息,因此左侧连接但成本太高了!因此,当我在 SQL-Dev 中调用此查询时,它只是停留在那里 'loading' 并且需要很长时间,我不知道如何解决这个问题。

查询

SELECT event_user.*,
       dw_attendee.*
FROM event_user
    LEFT JOIN dw_attendee ON event_user.event_user_id = dw_attendee.event_user_id
    AND event_user.event_id = dw_attendee.event_id
    AND dw_attendee.session_id = 1
    AND event_user.event_id = :eventid;

计划

-------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |             |   130M|    44G|       |  2754K  (2)| 10:42:44 |       |       |
|*  1 |  HASH JOIN RIGHT OUTER|             |   130M|    44G|  4513M|  2754K  (2)| 10:42:44 |       |       |
|*  2 |   TABLE ACCESS FULL   | DW_ATTENDEE |    57M|  3861M|       |   106K  (8)| 00:24:45 |       |       |
|   3 |   PARTITION RANGE ALL |             |   130M|    35G|       |   831K  (5)| 03:14:08 |     1 |  6044 |
|   4 |    TABLE ACCESS FULL  | EVENT_USER  |   130M|    35G|       |   831K  (5)| 03:14:08 |     1 |  6044 |
-------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("EVENT_USER"."EVENT_ID"="DW_ATTENDEE"."EVENT_ID"(+) AND 
              "EVENT_USER"."EVENT_USER_ID"="DW_ATTENDEE"."EVENT_USER_ID"(+) AND "EVENT_USER"."EVENT_ID"=CASE  WHEN 
              ("DW_ATTENDEE"."EVENT_USER_ID"(+) IS NOT NULL) THEN 2002317 ELSE 2002317 END )
   2 - filter("DW_ATTENDEE"."SESSION_ID"(+)=1)

我最初的想法是执行如下查询,因为单独执行的每个查询都非常快(成本为 0)

with reg as (select * from event_user where event_id = :eventid),
atd as (select * from dw_attendee where event_id = :eventid)
select distinct reg.*, atd.*
from reg left join atd on reg.event_id = atd.event_id;

上面的查询在成本 (172) 方面很好,但是我从这个查询得到的结果集太广泛了,它实际上是每行重复 20。

我的左table查询:

select * from event_user where event_id = 2002317;

returns30行,with reg as...查询returns600行!每行*20,任何指针?谢谢

在您的查询中,您将 event_user.event_id = :eventid 放在连接条件中,这意味着您没有过滤 event_user table。只要把它放在哪里,它就会更快。否则,您带回整个 event_user table 但尝试只加入一个特定的 event_id.

SELECT event_user.*,
       dw_attendee.*
FROM event_user
LEFT JOIN dw_attendee ON event_user.event_user_id = dw_attendee.event_user_id
                      AND event_user.event_id = dw_attendee.event_id
                      AND dw_attendee.session_id = 1
where event_user.event_id = :eventid;