在查询中获取第一行时的Oracle性能问题

时间:2013-01-29 03:44:46

标签: sql oracle oracle10g subquery

我在以下(示例)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通过执行SORTUNIQUE导致性能问题,但我无法找到替代方案。

但我更喜欢类似于以下的内容,但在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行。

赞赏提高表现的任何帮助。

2 个答案:

答案 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。

当然,您应该分析其他因素,例如索引,加入效率,查询计划等。