解决查询性能问题

时间:2017-08-16 02:55:18

标签: sql plsql oracle11g oracle-sqldeveloper

我一直无法了解/了解如何优化以下查询,我对性能提示非常陌生,所以也许有人可以给出一个指示:

顺便说一句,我需要保留左表(event_user)中的所有信息,因此左边的连接,但成本只是离谱!因此,当我在SQL-Dev中调用此查询时,它只会停留在那里并加载'并且需要很长时间,而且我不知道如何接受这个。

查询

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次。

我的左表查询:

select * from event_user where event_id = 2002317;

返回30行,with reg as...查询返回600!每行* 20,任何指针?谢谢

1 个答案:

答案 0 :(得分:2)

在您的查询中,您将event_user.event_id = :eventid置于连接条件中这意味着您没有过滤event_user表。把它放在哪里,它会更快。 Otherwitse,你带回整个event_user表,但尝试只加入一个特定的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;