Oracle查询性能行为不一致

时间:2015-03-06 10:11:57

标签: java sql oracle rownum

考虑以下问题:

SELECT * 
  FROM (
    SELECT ARRM.*, ROWNUM 
    FROM CRS_ARRANGEMENTS ARRM 
    WHERE 
       CONCAT(ARRM.NBR_ARRANGEMENT, ARRM.TYP_PRODUCT_ARRANGEMENT) > 
       CONCAT('0000000000000000', '0000') 
    ORDER BY 
      ARRM.NBR_ARRANGEMENT, 
      ARRM.TYP_PRODUCT_ARRANGEMENT, 
      ARRM.COD_CURRENCY) 
WHERE ROWNUM < 1000;

此查询在具有10 000 000个条目的表上运行。从Oracle SQL Developer或我的应用程序运行查询时,运行需要4分钟!不幸的是,这也是我写作的应用程序内部的行为。将值从1000更改为10根本没有任何影响,表明它正在进行全表扫描。

但是,当从SQuirreL运行时,查询会在几毫秒内返回 。怎么可能?在SQuirreL中生成的解释计划给出了:

Explain plan in SQuirreL

但是,对于相同的查询,Oracle SQL Developer中会生成不同的解释计划:

Explain plan in Oracle SQL Developer

知道这种行为差异怎么可能?我无法理解它。我尝试使用JPA和原始JDBC。在应用程序中,我需要解析所有10 000 000条记录,并且此查询用于分页,因此等待4分钟不是一个选项(需要27天)。

注意:我在SQuirreL和我的应用程序中使用相同的Oracle jdbc驱动程序,因此这不是问题的根源。

1 个答案:

答案 0 :(得分:1)

显然,国家语言支持或NLS参数与它有关。 Oracle SQL Developer将它们设置为&#34; Dutch&#34;,默认设置基于您的Locale,而SQuirreL将其设置为BINARY。这种差异使优化器使用不同的路径来解决查询。要在jdbc会话中使用正确的NLS_SORT参数,需要使用以下命令:

ALTER SESSION SET NLS_SORT=BINARY

然后将在查询中使用正确的索引。