我在以下(示例)select语句中遇到性能问题,该语句使用子查询返回第一行:
SELECT ITEM_NUMBER,
PROJECT_NUMBER,
NVL((SELECT DISTINCT
FIRST_VALUE(L.LOCATION) OVER (ORDER BY L.SORT1, L.SORT2 DESC) LOCATION
FROM LOCATIONS L
WHERE L.ITEM_NUMBER=P.ITEM_NUMBER
AND L.PROJECT_NUMBER=P.PROJECT_NUMBER
),
P.PROJECT_NUMBER) LOCATION
FROM PROJECT P
DISTINCT
通过执行SORT
和UNIQUE
导致性能问题,但我无法找到替代方案。
但我更喜欢类似于以下的内容,但在2个select语句中引用不起作用:
SELECT ITEM_NUMBER,
PROJECT_NUMBER,
NVL((SELECT LOCATION
FROM (SELECT L.LOCATION LOCATION
ROWNUM RN
FROM LOCATIONS L
WHERE L.ITEM_NUMBER=P.ITEM_NUMBER
AND L.PROJECT_NUMBER=P.PROJECT_NUMBER
ORDER BY L.SORT1, L.SORT2 DESC
) R
WHERE RN <=1
), P.PROJECT_NUMBER) LOCATION
FROM PROJECT P
此外: - 我的权限不允许我创建一个函数。 - 我在主查询中循环访问10k到100k的记录。 - 在限制为1行之前,子查询可以返回3到7行。
赞赏提高表现的任何帮助。
答案 0 :(得分:3)
如果没有样本数据和基数,这很难理解,但这样可以得到你想要的吗?项目和项目的唯一列表,第一次出现位置?
SELECT
P.ITEM_NUMBER,
P.PROJECT_NUMBER,
MIN(L.LOCATION) KEEP (DENSE_RANK FIRST ORDER BY L.SORT1, L.SORT2 DESC) LOCATION
FROM
LOCATIONS L
INNER JOIN
PROJECT P
ON L.ITEM_NUMBER=P.ITEM_NUMBER
AND L.PROJECT_NUMBER=P.PROJECT_NUMBER
GROUP BY
P.ITEM_NUMBER,
P.PROJECT_NUMBER
答案 1 :(得分:-2)
我在过去遇到过类似的问题 - 虽然这不是最终的解决方案(实际上可能只是一个切角) - 可以使用OPTIMIZER_MODE init参数调整Oracle查询优化器。
查看http://docs.oracle.com/cd/B28359_01/server.111/b28274/optimops.htm#i38318
上的第11.2.1章FIRST_ROWS
优化程序使用成本和启发式的组合来查找最佳计划 用于快速交付前几行。注意:使用启发式 有时会引导查询优化器生成带有成本的计划 这远远大于未申请的计划成本 启发式。 FIRST_ROWS可用于向后兼容和 计划稳定;改为使用FIRST_ROWS_n。
当然,您应该分析其他因素,例如索引,加入效率,查询计划等。