0

我在以下(示例)选择语句中遇到性能问题,该语句使用子查询返回第一行:

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

通过执行 a andDISTINCT导致性能问题,但我无法找到替代方案。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 行。

感谢您对提高性能的任何帮助。

4

2 回答 2

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
于 2013-01-29T05:57:57.747 回答
-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。

当然还有很多其他因素你应该分析,比如你的索引、连接效率、查询计划等等。

于 2013-01-29T03:47:54.510 回答