【发布时间】:2017-02-24 08:25:26
【问题描述】:
我正在使用 Oracle 11gR2 和 Hibernate 4.2.1。 我的应用程序是搜索应用程序。
只有 SELECT 操作,都是原生查询。
Oracle 默认使用区分大小写的排序。 我想将其覆盖为不区分大小写。
我在这里看到了几个选项http://docs.oracle.com/cd/A81042_01/DOC/server.816/a76966/ch2.htm#91066
现在我在执行任何搜索之前使用此查询。
ALTER SESSION SET NLS_SORT='BINARY_CI'
如果我在执行搜索查询之前执行上述 sql,则休眠大约需要 15 分钟才能从搜索查询返回。 如果我在 Sql Developer 中执行此操作,它会在几秒钟内返回。
为什么会有这种两种不同的行为, 我该怎么做才能摆脱这种缓慢?
注意:我总是为每次搜索打开一个新的 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 upper(B) asc Sql Developer 也需要同样的时间。
但按结果排序与NLS_SORT=BINARY_CI 相同。我使用了UPPER('B') 索引,但没有什么对我有用。
A 的长度 = 10-15 个字符
B 的长度 = 34-50 个字符
C 的长度 = 5-10 个字符
A、B 和 C 是可通过 app 排序的字段。 这个 SRC 表有 300 万多条记录。 我们最终得到了一个 SRC 表,它是一个物化视图。
SQL 的业务逻辑完全没问题。 所有的排序表字段和其他字段都被 UPPER 索引。
【问题讨论】:
-
您是说
ALTER SESSION只会对通过休眠的查询产生负面影响吗?ALTER可以很容易地阻止索引访问路径,使查询显着变慢。但它应该在 SQL Developer 中以相同的方式工作。您确定两个环境都在运行完全相同的 SQL 语句吗? -
@jonearles 是的,我运行了相同的查询。但是通过休眠它不是一个单一的SQL。我必须使用同一个会话执行 2 个查询。在 Sql developer 上,我打开一个选项卡,运行
ALTER查询,然后在同一选项卡中运行SELECT *...ORDER BY查询。工作正常。那里没有缓慢。有时这可能不是我想的 Hibernate 问题。但这正在发生:( -
您能否发布通过 hibernate 和 SQL Developer 对数据库运行的确切 SQL 语句?解决方案可能是创建具有特定排序的基于函数的索引,但我们需要查看查询才能确定。
-
我将发布 sql。我使用了
UPPER()索引。
标签: sql oracle hibernate query-performance