几天来,我一直在为针对 Oracle 数据库的 hibernate 查询而苦苦挣扎。 类似这样的东西用于将记录提供给网格。
SELECT
fields
FROM
tables and JoinedTables
WHERE
Field1 >= :value1
AND Field2 = :value2
AND Field3 = :value3
Order By MaintTable.Id Desc
在 Spring Java + Hibernate 4.2 方法中使用此方法。
SQLQuery query = (SQLQuery) session.createSQLQuery(querySql)
.addEntity(CertificateViewEnt.class)
.setParameter("value1", firstCertificateRecordDate)
.setParameter("value2", certType.toUpperCase())
.setParameter("value3", deleted? 1:0);
每个过滤字段都正确索引并在 Maintable.Id Descendent 上创建函数索引以提高性能。
一开始以为是session/connection pool没有被正确管理,所以改成StatelessSession,加上这个session.close():
query.setCacheable(false)
.setTimeout(30)
.setReadOnly(true);
...
...
//Pagination
query.setMaxResults(rows);
query.setFirstResult(HelperMethod(page, rows));
result = (List<CertificateViewEnt>) query.list();
session.close();
return result;
没有解决。 查询运行几次正常,但由于某些未知原因,并且使用之前已成功运行的值,挂起,使 session 在 Oracle 中打开(状态= Activity )并因超时而失败。 在任何 SQL 客户端上针对 Oracle 运行相同的查询,并使用所有可能的参数组合执行数十次,以极高的性能执行,大约 400 毫秒,一次处理 10 条记录。
在阅读了一些文章之后, Link1 [ Slow performance on Hibernate + Java but fast when I use TOAD with the same native Oracle query 链接2:[query hangs oracle 10g
我怀疑 Hibernate 使用的 QueryPlan 很糟糕,因此决定删除所有使用绑定(bind)参数的过滤器,但也没有解决,尽管它稍微好一点。移动到第 1、2、3、4 页等其他页面时挂了一会儿,......
毕竟,我怀疑Hibernate的方法生成的SQL
query.setMaxResults(rows)
query.setFirstResult(SomeHelperMethod(page, rows));
因为在日志中看到它们作为绑定(bind)参数传递给 Oracle。
...
Order By Certificado.Id Desc ) row_
where rownum <= ?)
where rownum_ > ?
我在跟踪日志中也看到了这一点
2015-09-15 14:09:53 TRACE QueryPlanCache:200 - Located native-sql query plan in cache (SELECT /*+ INDEX(
还有这个:
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [2] as [VARCHAR] - E
2015-09-15 14:09:53 DEBUG Loader:2031 - bindNamedParameters() 0 -> deleted [3]
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [3] as [INTEGER] - 0
2015-09-15 14:09:53 TRACE Loader:1931 - Bound [7] parameters total
/*
SLOW here !!! Around 3 secs when query runs in ~0,300 secs via SQL client.
And ACTIVE sessions are left running in Oracle.
*/
2015-09-15 14:09:56 TRACE JdbcCoordinatorImpl:397 - Registering result set [org.apache.commons.dbcp.DelegatingResultSet@f0c620]
2015-09-15 14:09:56 TRACE Loader:943 - Processing result set
最后我不得不放弃所有 Hibernate 绑定(bind)参数并实现自定义计算分页并编写所有 SQL 来检索页面行并且它正在运行并正确管理数据库 session 。
那么,我的问题是: hibernate 在阻止查询在针对数据库运行时运行的场景中做了什么? 绑定(bind)参数查询是否存在任何已知问题?
当我有绑定(bind)参数时,我真的不喜欢编写所有 SQL 代码并强制硬解析此 SQL。
关于环境的一些注意事项: Tomcat 和 Oracle 在同一台主机上。所以网络连接不是问题
Hibernate 4.2.15 最终版
该表在开发数据库中有大约 30 万条记录(生产中有 1.5 万条记录),一次显示 10、20、50 条记录的页面,按主键降序排序(生成的序列)
希望一些 Hibernate 专家可以帮助我,这样我仍然可以信任大型数据库项目中的 Hibernate 查询。 提前致谢。
最佳答案
我不知道这是否是您的问题,但 Oracle 在解析查询时会查看绑定(bind)变量值,然后保存查询计划以供将来执行,因此它不必在每次运行时都继续解析查询使用一组新的绑定(bind)变量。但是每隔一段时间就会重新解析查询。如果在解析过程中碰巧传递了一些不寻常的绑定(bind)变量值,则会存储和使用错误的计划。这是一种绑定(bind)变量的诅咒。它们减少了解析,但可以在再次解析查询时根据非典型的绑定(bind)变量值翻转计划。提示可以提供帮助。我们使用 SQL 配置文件来锁定带有绑定(bind)变量的查询计划,这些变量往往会改变计划。有时您可以自定义收集优化器统计信息的时间和方式,以便无论将什么值传递到绑定(bind)变量都可以创建一个好的计划。
无论如何,这是我一直看到的事情,可能是也可能不是你的问题。
鲍比
关于java - Hibernate 参数化 sql 查询缓慢且活跃的 oracle session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32596761/
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一