考虑以下问题:
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中生成的解释计划给出了:
但是,对于相同的查询,Oracle SQL Developer中会生成不同的解释计划:
知道这种行为差异怎么可能?我无法理解它。我尝试使用JPA和原始JDBC。在应用程序中,我需要解析所有10 000 000条记录,并且此查询用于分页,因此等待4分钟不是一个选项(需要27天)。
注意:我在SQuirreL和我的应用程序中使用相同的Oracle jdbc驱动程序,因此这不是问题的根源。
答案 0 :(得分:1)
显然,国家语言支持或NLS参数与它有关。 Oracle SQL Developer将它们设置为&#34; Dutch&#34;,默认设置基于您的Locale,而SQuirreL将其设置为BINARY。这种差异使优化器使用不同的路径来解决查询。要在jdbc会话中使用正确的NLS_SORT参数,需要使用以下命令:
ALTER SESSION SET NLS_SORT=BINARY
然后将在查询中使用正确的索引。