【发布时间】:2026-01-14 21:20:03
【问题描述】:
我有一个表 TRANSACTIONS,其中包含近 3000 万个事务(13 列)。如何优化以下代码?我尝试了自我加入,但它似乎不太有效。
逻辑:如果 receiver_2 存在,我想通过 sender-receiver_2 获取最后交易,否则通过 sender-receiver + 计算一些统计信息( 10/30/90 天)
SELECT T.* FROM
(SELECT T.*, row_number() over (partition by T.SENDER, (CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END) order by T.DATE_ACCEPT desc) as seqnum
FROM
(
SELECT T.*
,(SELECT COUNT(DISTINCT T2.ID_TRAN)
FROM TRANSACTIONS T2
WHERE T2.DATE_ACCEPT > T.DATE_ACCEPT - 10 AND
T2.DATE_ACCEPT < T.DATE_ACCEPT AND
(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.RECEIVER ELSE T2.RECEIVER_2 END) =
(CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END)
AND
T2.SENDER = T.SENDER
) CNT_10
,(SELECT COUNT(DISTINCT T2.ID_TRAN)
FROM TRANSACTIONS T2
WHERE T2.DATE_ACCEPT > T.DATE_ACCEPT - 30 AND
T2.DATE_ACCEPT < T.DATE_ACCEPT AND
(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.RECEIVER ELSE T2.RECEIVER_2 END) =
(CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END)
AND
T2.SENDER = T.SENDER
) CNT_30
,(SELECT COUNT(DISTINCT T2.ID_TRAN)
FROM TRANSACTIONS T2
WHERE T2.DATE_ACCEPT > T.DATE_ACCEPT - 90 AND
T2.DATE_ACCEPT < T.DATE_ACCEPT AND
(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.RECEIVER ELSE T2.RECEIVER_2 END) =
(CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END)
AND
T2.SENDER = T.SENDER
) CNT_90
,(SELECT DISTINCT AVG(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.AMOUNT ELSE T2.AMOUNT_2 END) OVER()
FROM TRANSACTIONS T2
WHERE T2.DATE_ACCEPT > T.DATE_ACCEPT - 10 AND
T2.DATE_ACCEPT < T.DATE_ACCEPT AND
(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.RECEIVER ELSE T2.RECEIVER_2 END) =
(CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END)
AND
T2.SENDER = T.SENDER
GROUP BY T2.ID_TRAN, (CASE WHEN T.RECEIVER_2 IS NULL THEN T2.AMOUNT ELSE T2.AMOUNT_2 END)
) AVG_AMOUNT_10
,(SELECT DISTINCT AVG(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.AMOUNT ELSE T2.AMOUNT_2 END) OVER()
FROM TRANSACTIONS T2
WHERE T2.DATE_ACCEPT > T.DATE_ACCEPT - 30 AND
T2.DATE_ACCEPT < T.DATE_ACCEPT AND
(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.RECEIVER ELSE T2.RECEIVER_2 END) =
(CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END)
AND
T2.SENDER = T.SENDER
GROUP BY T2.ID_TRAN, (CASE WHEN T.RECEIVER_2 IS NULL THEN T2.AMOUNT ELSE T2.AMOUNT_2 END)
) AVG_AMOUNT_30
,(SELECT DISTINCT AVG(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.AMOUNT ELSE T2.AMOUNT_2 END) OVER()
FROM TRANSACTIONS T2
WHERE T2.DATE_ACCEPT > T.DATE_ACCEPT - 90 AND
T2.DATE_ACCEPT < T.DATE_ACCEPT AND
(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.RECEIVER ELSE T2.RECEIVER_2 END) =
(CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END)
AND
T2.SENDER = T.SENDER
GROUP BY T2.ID_TRAN, (CASE WHEN T.RECEIVER_2 IS NULL THEN T2.AMOUNT ELSE T2.AMOUNT_2 END)
) AVG_AMOUNT_90
,(SELECT MAX(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.AMOUNT ELSE T2.AMOUNT_2 END)
FROM TRANSACTIONS T2
WHERE T2.DATE_ACCEPT > T.DATE_ACCEPT - 10 AND
T2.DATE_ACCEPT < T.DATE_ACCEPT AND
(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.RECEIVER ELSE T2.RECEIVER_2 END) =
(CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END)
AND
T2.SENDER = T.SENDER
) MAX_AMOUNT_10
,(SELECT MAX(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.AMOUNT ELSE T2.AMOUNT_2 END)
FROM TRANSACTIONS T2
WHERE T2.DATE_ACCEPT > T.DATE_ACCEPT - 30 AND
T2.DATE_ACCEPT < T.DATE_ACCEPT AND
(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.RECEIVER ELSE T2.RECEIVER_2 END) =
(CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END)
AND
T2.SENDER = T.SENDER
) MAX_AMOUNT_30
,(SELECT MAX(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.AMOUNT ELSE T2.AMOUNT_2 END)
FROM TRANSACTIONS T2
WHERE T2.DATE_ACCEPT > T.DATE_ACCEPT - 90 AND
T2.DATE_ACCEPT < T.DATE_ACCEPT AND
(CASE WHEN T.RECEIVER_2 IS NULL THEN T2.RECEIVER ELSE T2.RECEIVER_2 END) =
(CASE WHEN T.RECEIVER_2 IS NULL THEN T.RECEIVER ELSE T.RECEIVER_2 END)
AND
T2.SENDER = T.SENDER
) MAX_AMOUNT_90
FROM TRANSACTIONS T
) T ) T
WHERE T.SEQNUM = 1
我还在 (SENDER, DATE_ACCEPT) 上创建了索引。
【问题讨论】:
-
请添加带索引的查询计划
-
您的 SQL 中可能存在复制粘贴错误:您的子查询中总是有
WHEN T.RECEIVER_2 IS NULL THEN,但是,也应该使用WHEN T2.RECEIVER_2 IS NULL THEN。 -
您能否提供所需的结果(基于您的样本数据)?请将表格数据提供为表格,而不是截图,请参阅meta.*.com/q/285551
标签: sql oracle optimization