考虑以下查询:

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;


此查询在具有10000000条目的表上运行。从Oracle SQL Developer或我的应用程序运行查询时,需要4分钟才能运行!不幸的是,这也是我正在编写的应用程序内部的行为。将该值从1000更改为10完全没有影响,表明它正在执行全表扫描。

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



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



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

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

最佳答案

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

ALTER SESSION SET NLS_SORT=BINARY


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

10-06 12:58
查看更多