【发布时间】:2019-10-09 14:09:16
【问题描述】:
我的任务是根据一些规则获取特定帐户和交易。值得注意的是,账户和交易位于不同的表中,我的查询主要返回账户 - 比例约为 70 个账户与 1 笔交易。为了方便起见,我想将它们放在一个查询中 - 这是更大过程中的一个阶段。
原始查询:
SELECT DISTINCT
CASE
WHEN (a.transaction_type IN ('500', '501', '502', '920') AND a.transaction_date >= '#DATE#' AND to_char(a.transaction_date,'HH24') >= 16) THEN 'Transaction time'
WHEN b.closing_date >= '#DATE#' THEN 'Closing time'
WHEN b.opening_date >= '#DATE#' THEN 'Opening time'
WHEN (b.type = 'X' AND b.active = 'NO') THEN 'Frozen account'
END AS "comment"
,b.branch
,b.basic
,b.lmt
FROM
VDS.transactions a
JOIN VDS.accounts b ON a.acct_no = b.acct_no
WHERE
(a.transaction_type IN ('500', '501', '502', '920')
AND a.transaction_date >= '#DATE#'
AND to_char(a.transaction_date,'HH24') >= 16)
OR
(b.closing_date >= '#DATE#'
OR b.opening_date >= '#DATE#'
OR (b.type = 'X' AND b.active = 'NO'))
它似乎工作正常,即使有点慢 - 它的执行时间通常在 12 秒左右。问题是 - 有时根本无法完成。看起来数据库完全停留在查询上。由于我不是 Oracle 管理员,我无法证实我怀疑这是该查询的错,但多项测试表明确实如此。
所以我准备了另一种变体,考虑到交易比账户少得多。
带有子查询的变体:
SELECT
'Transaction time' AS "comment"
,b.branch
,b.basic
,b.lmt
FROM
VDS.transactions a
JOIN VDS.accounts b ON a.acct_no = b.acct_no
WHERE
a.transaction_type IN ('500', '501', '502', '920')
AND a.transaction_date >= '#DATE#'
AND to_char(a.transaction_date,'HH24') >= 16
UNION
SELECT
CASE
WHEN closing_date >= '#DATE#' THEN 'Closing time'
WHEN opening_date >= '#DATE#' THEN 'Opening time'
WHEN (type = 'X' AND active = 'NO') THEN 'Frozen account'
END AS "comment"
,branch
,basic
,lmt
FROM
VDS.accounts
WHERE
closing_date >= '#DATE#'
OR opening_date >= '#DATE#'
OR (type = 'X' AND active = 'NO'))
你瞧 - 执行时间缩短到大约 3-5 秒,查询不再阻塞数据库。它还返回了更多的结果,这很奇怪,但不是问题。
所以我的最后一个问题是:有人可以向我解释数据库的内部可能发生了什么,它很高兴地接受了带有子查询的变体,而原始的变体却变得不稳定?我可以更好地理解子查询的性能,但我不知道为什么查询有时会起作用,有时会完全挂断。
【问题讨论】:
-
您是否制定了解释计划并查看了结果?
-
我对 SQL 比较陌生,所以我什至不知道查询计划。感谢您提出!
标签: sql oracle query-performance