【问题标题】:how to optimize this below query in oracle?如何在 oracle 中优化以下查询?
【发布时间】:2015-08-19 00:33:11
【问题描述】:

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

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

如何优化这个查询?

【问题讨论】:

  • 获取解释计划,为关键列添加索引,获取新的解释计划,看看索引是否有帮助
  • 所有表都有相应的索引
  • 您认为它为什么需要进一步优化?

标签: sql oracle optimization query-optimization


【解决方案1】:

当您使用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

【讨论】:

  • 物化公用表表达式仅在公用表表达式多次使用时才有帮助。
  • 什么是物化公用表表达式?你能给我更多的信息吗?
猜你喜欢
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
  • 2017-06-15
  • 1970-01-01
  • 2021-11-19
  • 2011-03-25
  • 2020-05-29
  • 1970-01-01
相关资源
最近更新 更多