这让我疯狂。与直接通过 Navicat 运行该查询相比,使 hibernate 简单选择非常慢。更有趣的是什么。用本地数据库运行这个查询真的很快,但远程使用它真的很糟糕。
我正在执行以下 Hibernate native SQL 查询(因为 HQL 或 Criteria 不支持左连接):
List list = new ArrayList();
String queryStr = "select s.* from sales_unit s left join sales_unit_relation r on (s.sales_unit_id = r.sales_unit_child_id) where r.sales_unit_child_id is null";
Query query = session.createSQLQuery( queryStr ).addEntity( SalesUnit.class );
Long start = System.currentTimeMillis();
list.addAll( query.list() );
Long stop = System.currentTimeMillis();
System.out.println( "Time: " + (stop - start) + "ms." );
实体的结构并不重要。 SALES_UNIT 和 SALES_UNIT_RELATION 表都有大约 28k 条记录
结果,在我的 上运行本地JBoss 使用本地数据库,大约为 30-120 毫秒。在 上运行时远程 databasem,本地 JBoss(相同数据),导致时间在 30000-40000 毫秒之间。当我使用 Navicat 运行此查询时,本地和远程调用都非常快(20-30 毫秒)。
本地和远程数据库的安装方式相同 -> Oracle Enterprise Edition 11.2.0.1.0。
如此糟糕的性能可能是什么问题?我该如何调试它?
请阅读:Simple hibernate query returning very slowly ,但设置构造函数没有改变任何东西
编辑。
SALES_UNIT 表包含一些基本的销售单元节点信息,如名称等。唯一的关联是表 SALES_UNIT_TYPE,如 ManyToOne。主键是 ID,字段 VALID_FROM_DTTM 是日期。
SALES_UNIT_RELATION 包含销售单位节点之间的关系 PARENT-CHILD。由 SALES_UNIT_PARENT_ID、SALES_UNIT_CHILD_ID 和 VALID_TO_DTTM/VALID_FROM_DTTM 组成。与任何表没有关联。这里的PK是..PARENT_ID、..CHILD_ID和VALID_FROM_DTTM
最佳答案
谢谢大家的帮助。在这个问题上挣扎了很长时间后,最后 kaliatech 的回答帮助我调试了这个问题。
首先,我在我的问题中犯了一个可怕的错误。我写道:
Running this query with local database is really fast, but using it remotely is really poor.
因为这并不完全正确。我在 Hibernate 中所做的查询看起来像这样:
select s.* from sales_unit s left join sales_unit_relation r on (s.sales_unit_id = r.sales_unit_child_id) where r.sales_unit_child_id is null
但是我使用 SQL PLus 或 Navicat 进行的实际查询例如是:
select * from sales_unit s left join sales_unit_relation r on (s.sales_unit_id = r.sales_unit_child_id) where r.sales_unit_child_id is null
请注意第一个查询选择开始:
select s.* ...
第二个是 select * ...
.这就是表现如此糟糕的原因。现在这两个查询都很快就完成了。问题是,有什么区别:performance issue: difference between select s.* vs select *
关于sql - 与直接运行相比, hibernate 选择性能较差 - 如何调试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13306548/