【发布时间】:2022-01-18 16:06:57
【问题描述】:
我有这个问题:
SELECT
PE1.PRODUCT_EQUIPMENT_KEY, -- primary key
PE1.Customer_Ban,
PE1.Subscriber_No,
PE1.Prod_Equip_Cd,
PE1.Prod_Equip_Txt,
PE1.Prod_Equip_Category_Txt--,
-- PE2.ep_rnk ------------------ UNCOMMENT THIS LINE
FROM
INT_ADM.Product_Equipment_Dim PE1
INNER JOIN
(
SELECT
PRODUCT_EQUIPMENT_KEY,
ROW_NUMBER() OVER (PARTITION BY Customer_Ban, Subscriber_No ORDER BY Start_Dt ASC) AS ep_rnk
FROM INT_ADM.Product_Equipment_Dim PE2
) PE2
ON PE2.PRODUCT_EQUIPMENT_KEY = PE1.PRODUCT_EQUIPMENT_KEY
WHERE
Line_Of_Business_Cd = 'M'
AND /*v_Date_Start*/ TO_DATE( '2022/01/12', 'yyyy/mm/dd' ) BETWEEN Start_Dt AND End_Dt
AND Current_Ind = 'Y'
如果我按照你看到的那样运行它,那么它会在一秒钟内运行。
如果我在 -- PE2.ep_rnk ------------------ UNCOMMENT THIS LINE 未注释的情况下运行它,则查询最多需要 5 分钟才能完成。
我知道这与 ROW_NUMBER() 有关,但是在网上查遍之后,我找不到很好的解释和解决方案。有谁知道为什么取消注释该行会使查询变得如此缓慢,以及我能做些什么让它运行得快?
非常感谢您提前提供的帮助。
【问题讨论】:
-
该子查询强制为表中的 每一 行进行昂贵的行号计算,临时缓存响应,然后与数据子集进行昂贵的连接。那是你真正想要的吗?是否需要在过滤之前计算行号?否则,您可以将注释行替换为
ROW_NUMBER表达式 -
如果您注释该行,则忽略整个子查询,因为它不影响结果 - 子查询在 PK 上执行自联接,不会过滤任何行
-
执行计划是什么样的?您可以用返回所有必要字段 * 和行号的 CTE 或嵌套查询替换自联接,并使用外部查询过滤结果。查询引擎可能已经这样做了
-
重要提示 - 有多少行(与总行数相比)返回查询。另请了解如何检查(并发布)这两个查询的execution plan。
标签: sql oracle optimization