如何在oracle中优化以下查询?

时间:2015-08-18 10:10:55

标签: sql oracle optimization query-optimization

我的项目中有大量数据的这些树表:

core_department :最少300,000条记录

app_user :至少3,000条记录

app_user_department :至少3,000条记录

app_user_excluded_department :最少50条记录

core_department是部门表,每个记录都有hierarchy,此表数据应该像这样存储分层数据:

id  |title  |parentId   |hierarchy
-----------------------------------
1   |a      |null       |1
2   |b      |1          |1001
3   |c      |2          |1001001
4   |d      |3          |1001001001
5   |e      |3          |1001001002

我将用户的授权部门保存到app_user_department,并将未经授权的部门保存到app_user_excluded_department

例如,如果用户应该有权访问部门a 及其所有子项,我会将此记录保存到app_user_department

userId  |deparmentId
--------------------
1       |1

并排除部门c 及其所有子项,将此记录保存到app_user_excluded_department

userId  |deparmentId
--------------------
1       |3

最后,我将此调用称为以下特定用户的所有授权部门:

create or replace view user_authorize as
    select dp.id, queryResult.userId
    from core_department dp
    join (
            select u.id as userId, dpt.hierarchy as hierarchy
              from app_user u
              join app_user_department udp
                on u.id = udp.userId
              join core_department dpt
                on udp.departmentId = dpt.id
    ) queryResult
    on dp.hierarchy like queryResult.hierarchy || '%'

    minus

    select dp.id, queryResult.userId
    from core_department dp
    join (
            select u.id as userId, dpt.hierarchy as hierarchy
              from app_user u
              join app_user_excluded_department udp
                on u.id = udp.userId
              join core_department dpt
                on udp.departmentId = dpt.id
    ) queryResult
    on dp.hierarchy like queryResult.hierarchy || '%'


select *
from user_authorize ua
where ua.userId = 1

如何优化此查询?

1 个答案:

答案 0 :(得分:0)

当您使用WITH子句时,Oracle可能会创建临时表并在其中存储此类数据。因此,性能可以更好:

create or replace view user_authorize as
WITH queryResult_1 as 
(            select u.id as userId, dpt.hierarchy as hierarchy
              from app_user u
              join app_user_department udp
                on u.id = udp.userId
              join core_department dpt
                on udp.departmentId = dpt.id
    ),
queryResult_2 as
(            select u.id as userId, dpt.hierarchy as hierarchy
              from app_user u
              join app_user_excluded_department udp
                on u.id = udp.userId
              join core_department dpt
                on udp.departmentId = dpt.id
    )
    select dp.id, queryResult_1.userId
    from core_department dp
    join queryResult_1 
    on dp.hierarchy like queryResult_1.hierarchy || '%'

    minus

    select dp.id, queryResult_2.userId
    from core_department dp
    join queryResult_2
    on dp.hierarchy like queryResult_2.hierarchy || '%'


select *
from user_authorize ua
where ua.userId = 1