Sql Alter会话通过Hibernate减慢查询速度

Sql Alter会话通过Hibernate减慢查询速度,sql,oracle,hibernate,query-performance,Sql,Oracle,Hibernate,Query Performance,我正在使用Oracle11gr2和Hibernate4.2.1。 我的应用程序是一个搜索应用程序 只有SELECT操作,并且所有操作都是本机查询 Oracle默认使用区分大小写的排序。 我想将其改写为不区分大小写 我在这里看到了几个选择 现在我在执行任何搜索之前使用这个查询 ALTER SESSION SET NLS_SORT='BINARY_CI' 如果我在执行搜索查询之前执行上述sql,hibernate从搜索查询返回大约需要15分钟。 如果在SQLDeveloper中执行此操作,它将在几

我正在使用Oracle11gr2和Hibernate4.2.1。 我的应用程序是一个搜索应用程序

只有SELECT操作,并且所有操作都是本机查询

Oracle默认使用区分大小写的排序。 我想将其改写为不区分大小写

我在这里看到了几个选择

现在我在执行任何搜索之前使用这个查询

ALTER SESSION SET NLS_SORT='BINARY_CI'
如果我在执行搜索查询之前执行上述sql,hibernate从搜索查询返回大约需要15分钟。 如果在SQLDeveloper中执行此操作,它将在几秒钟内返回

为什么这两种不同的行为,, 我能做些什么来摆脱这种缓慢

注意:每次搜索我都会打开一个新的Hibernate会话

以下是我的sql:

SELECT *
FROM (SELECT
        row_.*,
        rownum rownum_
      FROM (SELECT
               a, b, c, d, e,
               RTRIM(XMLAGG(XMLELEMENT("x", f || ', ') ORDER BY f ASC)
                     .extract('//text()').getClobVal(), ', ') AS f,
               RTRIM(
                  XMLAGG(XMLELEMENT("x", g || ', ') ORDER BY g ASC)
                  .extract('//text()').getClobVal(), ', ')    AS g
             FROM ( SELECT src.a, src.b, src.c, src.d, src.e, src.f, src.g
                      FROM src src
                     WHERE upper(pp) = 'PP'
                       AND upper(qq) = 'QQ'
                       AND upper(rr) = 'RR'
                       AND upper(ss) = 'SS'
                       AND upper(tt) = 'TT')
             GROUP BY a, b, c, d, e
             ORDER BY b ASC) row_
      WHERE rownum <= 400
) WHERE rownum_ > 0;
有很多字段与LIKE操作一起提供,这是一个动态sql查询。若我使用order by upperB asc,Sql开发人员也需要同样的时间。 但按上限排序的结果与NLS_SORT=BINARY_CI相同。我使用了较高的“B”索引,但对我来说没有任何效果

A的长度=10-15个字符

B的长度=34-50个字符

C的长度=5-10个字符

A、 B和C是可通过应用程序排序的字段。 此SRC表有300多万条记录。 我们最终得到了一个SRC表,它是一个物化视图

SQL的业务逻辑是完全正确的。
所有sor表字段和其他字段都是上标的。

上标和二进制\u CI可能产生相同的结果,但Oracle不能互换使用它们。要使用索引和二进制CI,必须创建如下索引:

create index src_nlssort_index on src(nlssort(b, 'nls_sort=''BINARY_CI'''));
样本表和混合案例数据

BINARY_CI和Language将不使用索引

基于NLSSORT的函数索引启用索引范围扫描


我调查发现,参数NLS_COMP y NLS_SORT可能会影响oracle在比较或排序时如何使用字符串执行计划

无需更改NLS会话。添加

ORDER BY NLSSORT(column , 'NLS_SORT=BINARY_CI') 
为NLS添加索引就足够了

create index column_index_binary as NLSSORT(column , 'NLS_SORT=BINARY_CI')
我在这个问题上找到了一个问题的线索,所以我要偿还


你是说ALTER会话只会通过hibernate对查询产生负面影响吗?这种改变可以很容易地阻止索引访问路径,使查询速度大大降低。但在SQLDeveloper中,它应该以同样的方式工作。您确定两个环境运行的SQL语句完全相同吗?@jonearles是的,我运行了相同的查询。但通过hibernate,它不是一个单一的SQL。我必须使用同一个会话执行两个查询。在Sql developer上,我打开一个选项卡,运行ALTER查询,然后在同一选项卡中运行SELECT*…ORDER BY查询。很好。没有慢下来。有时我想这可能不是一个休眠问题。但这正在发生:您可以通过hibernate和SQL Developer发布针对数据库运行的确切SQL语句吗?解决方案可能是创建具有特定排序的基于函数的索引,但我们需要查看查询才能确定。我将发布sql。我使用了较高的索引,但它仍然在发生。最后,我添加了3个额外的列UPPER_A、UPPER_B、UPPER_C作为临时解决方案。现在我只是按上_B排序。这可能不是一个好的解决方案。但现在我同意这一点。我尝试了所有我能想到的组合,而没有考虑它们的目的。没有一个成功。而且这种情况只发生在少数搜索场景中。我们在UAT阶段发现了这一点。所有其他人都按上级的平均顺序工作。如果我使用任何索引或将ORDER BY UPPER放入最内部的SELECT中,它就会工作。但那不是我想做的。聚合选择查询不喜欢这些索引,按上限排序或更改NLS_排序有时仅适用于某些场景。
alter session set nls_sort='binary_ci';
alter session set nls_comp='linguistic';

explain plan for
select * from src where b = 'MIXED CASE 1';

select * from table(dbms_xplan.display(format => '-rows -bytes -cost -note'));

Plan hash value: 3368256651

---------------------------------------------
| Id  | Operation         | Name | Time     |
---------------------------------------------
|   0 | SELECT STATEMENT  |      | 00:00:02 |
|*  1 |  TABLE ACCESS FULL| SRC  | 00:00:02 |
---------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(NLSSORT("B",'nls_sort=''BINARY_CI''')=HEXTORAW('6D69786564
              2063617365203100') )
create index src_nlssort_index on src(nlssort(b, 'nls_sort=''BINARY_CI'''));

explain plan for
select * from src where b = 'MIXED CASE 1';

select * from table(dbms_xplan.display(format => '-rows -bytes -cost -note'));

Plan hash value: 478278159

--------------------------------------------------------------------
| Id  | Operation                   | Name              | Time     |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                   | 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| SRC               | 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | SRC_NLSSORT_INDEX | 00:00:01 |
--------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access(NLSSORT("B",'nls_sort=''BINARY_CI''')=HEXTORAW('6D69786564
              2063617365203100') )
ORDER BY NLSSORT(column , 'NLS_SORT=BINARY_CI') 
create index column_index_binary as NLSSORT(column , 'NLS_SORT=BINARY_CI')