Oracle查询性能行为不一致 [英] Oracle inconsistent performance behaviour of query

查看:109
本文介绍了Oracle查询性能行为不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下查询:

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完全没有影响,表明它正在执行全表扫描.

This query runs on a table that has 10 000 000 entries. When running the query from Oracle SQL Developer or my application it takes 4 minutes to run! 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.

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

However when running from SQuirreL the query returns within a few milliseconds. How is that possible? Explain plan generated in SQuirreL gives:

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

But a different explain plan is generated in Oracle SQL Developer, for the same query:

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

Any idea how this difference in behaviour is possible? I can't get to understand it. I tried with JPA and raw 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).

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

Note: I'm using the same Oracle jdbc driver in SQuirreL and my application so that is not the source of the problem.

推荐答案

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

Apparently the National Language Support or NLS parameters had something to do with it. Oracle SQL Developer had them set to "Dutch", default setting based on your Locale, while SQuirreL has it set to 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:

ALTER SESSION SET NLS_SORT=BINARY

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

Then the correct indexes will be used on the query.

这篇关于Oracle查询性能行为不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆