Oracle group by 和 OR 查询优化
Posted
技术标签:
【中文标题】Oracle group by 和 OR 查询优化【英文标题】:Oracle group by and OR query optimization 【发布时间】:2020-03-13 05:54:26 【问题描述】:SELECT BATCH_ID,
BU_CODE,
BU_TYPE,
BATCH_TYPE,
BATCH_GROUP_ID,
STATUS,
UPD_DTIME
FROM BATCH_T
WHERE (BU_CODE, BU_TYPE, BATCH_TYPE, UPD_DTIME) IN
(SELECT BU_CODE,
BU_TYPE,
BATCH_TYPE,
MAX(UPD_DTIME)
FROM BATCH_T
WHERE STATUS = 'CLOSED'
GROUP BY BU_CODE,
BU_TYPE,
BATCH_TYPE
)
OR UPD_DTIME >= SYSDATE - 5;
如上面没有 OR 条件的 Oracle Query 它给出快速响应,但有 OR 条件它需要这么多时间。能否请您帮助如何提高上述查询的响应时间。
【问题讨论】:
执行计划将有助于确定问题 【参考方案1】:您需要最近关闭的记录以及过去五天的所有内容。使用窗口函数!
SELECT b.*
FROM (SELECT b.*,
ROW_NUMBER() OVER (PARTITION BY BU_CODE, BU_TYPE, BATCH_TYPE, STATUS ORDER BY UPD_DTIME DESC) as seqnum
FROM BATCH_T b
) b
WHERE UPD_DTIME >= SYSDATE - 5 OR
(STATUS = 'CLOSED' AND seqnum = 1);
这应该比使用IN
/EXISTS
和聚合的任何方法都快。写起来也比较简单。
【讨论】:
'OR BATCH_ID IN (SELECT BATCH_ID FROM BATCH_T batch JOIN BATCH_GROUP_T batchGroup ON batch.BATCH_GROUP_ID = batchGroup.BATCH_GROUP_ID WHERE batchGroup.STATUS != 'CLOSED')' ** 我需要再添加 1 个 OR 条件对上面的查询,我可以直接添加吗,会不会导致任何性能问题。欢迎提出建议。** @Gangs165700 。 . .您应该能够向此查询添加其他条件。【参考方案2】:以这样的方式拆分查询,其中应该有AND
条件以获得如下所示的性能增益。
SELECT BATCH_ID,
BU_CODE,
BU_TYPE,
BATCH_TYPE,
BATCH_GROUP_ID,
STATUS,
UPD_DTIME
FROM BATCH_T
WHERE UPD_DTIME >= SYSDATE - 5
UNION ALL
SELECT BATCH_ID,
BU_CODE,
BU_TYPE,
BATCH_TYPE,
BATCH_GROUP_ID,
STATUS,
UPD_DTIME
FROM BATCH_T
WHERE (BU_CODE, BU_TYPE, BATCH_TYPE, UPD_DTIME) IN
(SELECT BU_CODE,
BU_TYPE,
BATCH_TYPE,
MAX(UPD_DTIME)
FROM BATCH_T
WHERE STATUS = 'CLOSED'
GROUP BY BU_CODE,
BU_TYPE,
BATCH_TYPE
) AND NOT UPD_DTIME >= SYSDATE - 5;
【讨论】:
我需要在上面的查询中再添加 1 个 OR 条件,如下所示, 尝试在该新查询中排除上述 2 个查询结果,并将其与上述查询的所有联合包括在内 我可以用 Union 代替 Union All 吗?【参考方案3】:您可以为 UPD_DTIME 创建索引
【讨论】:
以上是关于Oracle group by 和 OR 查询优化的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 查询优化与 group by 和 order by rand