简体   繁体   English

Oracle查询性能行为不一致

[英]Oracle inconsistent performance behaviour of query

Consider the following query: 考虑以下查询:

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;

This query runs on a table that has 10 000 000 entries. 该查询在具有10000000条目的表上运行。 When running the query from Oracle SQL Developer or my application it takes 4 minutes to run ! 从Oracle SQL Developer或我的应用程序运行查询时, 需要4分钟才能运行 Unfortunately that is also the behaviour inside the application that I'm writing. 不幸的是,这也是我正在编写的应用程序内部的行为。 Changing the value from 1000 to 10 has no impact at all, suggesting that it is doing a full table scan. 将值从1000更改为10完全没有影响,表明它正在执行全表扫描。

However when running from SQuirreL the query returns within a few milliseconds . 但是,从SQuirreL运行时,查询将在几毫秒内返回。 How is that possible? 那怎么可能? Explain plan generated in SQuirreL gives: 在SQuirreL中生成的解释计划给出:

在SQuirreL中解释计划

But a different explain plan is generated in Oracle SQL Developer, for the same query: 但是对于相同的查询,Oracle SQL Developer中生成了一个不同的解释计划:

在Oracle SQL Developer中解释计划

Any idea how this difference in behaviour is possible? 知道这种行为差异怎么可能吗? I can't get to understand it. 我无法理解。 I tried with JPA and raw JDBC. 我尝试使用JPA和原始JDBC。 In the application I need to parse through all 10 000 000 records and this query is used for the paging, so waiting 4 minutes is not an option (that would take 27 days). 在应用程序中,我需要解析所有10000000条记录,并且此查询用于分页,因此等待4分钟不是一个选择(这将花费27天)。

Note : I'm using the same Oracle jdbc driver in SQuirreL and my application so that is not the source of the problem. 注意 :我在SQuirreL和我的应用程序中使用了相同的Oracle jdbc驱动程序,因此这不是问题的根源。

Apparently the National Language Support or NLS parameters had something to do with it. 显然,国家语言支持或NLS参数与它有关。 Oracle SQL Developer had them set to "Dutch", default setting based on your Locale, while SQuirreL has it set to BINARY. Oracle SQL Developer将其设置为“ Dutch”,这是基于您的语言环境的默认设置,而SQuirreL则将其设置为BINARY。 This difference made the optimizer use different paths to solve the query. 这种差异使优化器使用不同的路径来解决查询。 In order to use the correct NLS_SORT parameter in the jdbc session the following command needs to be used: 为了在jdbc会话中使用正确的NLS_SORT参数,需要使用以下命令:

ALTER SESSION SET NLS_SORT=BINARY

Then the correct indexes will be used on the query. 然后将在查询上使用正确的索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM