10

我正在尝试检测和优化 Java/Hibernate 应用程序中的低效连接。我注意到在某些情况下,由于在结果集中处理连接的方式的性质,无线数据流的效率非常低。

让我举个例子。假设您有一个如下所示的 HQL 查询:

select s from Store s
left join fetch s.items i
left join fetch s.employees e
left join fetch s.customers c
where s.id = :id

(暂时忽略这不是一个智能查询 - 它只是一个简化的示例)。

如果您想象一个给定的商店有 1000 件商品、10 名员工和 100 名客户,您将得到一个包含 1111 个实体的 java 对象树。这可能会让您误以为从数据库返回了大约 1111 行,而实际上结果集有 1,000,000 行!

所有列的存在使情况变得更糟。如果您想像每个表有 5 列,您可能会想像您得到了大约 5555 个“项目”,而结果集中的单元格数(行 * 列)实际上是 20,000,000。

显然,应用程序开发人员有责任意识到这个问题并且不以这种方式编写查询。然而,这有时会无意中发生(并且以不太严重的方式),如果能够检测应用程序以某种方式识别这些情况,那就太好了。

但是,我一直无法找到任何方法来计算(从 Java/Hibernate 应用程序中)原始结果集中的行数或列数。Hibernate 拦截器、Hibernate 事件和 Hibernate 统计信息似乎都无法访问此信息。

有什么建议么?提前致谢。

4

3 回答 3

2

有一个名为log4jdbc的项目提供代理 JDBC 驱动程序,它可以记录 SQL(添加了绑定参数)以及计时统计信息、连接打开和关闭事件,甚至 ResultSet 调用。有几个分支,至少一个(称为log4jdbc-remix)将结果集记录为表。

我认为使用jdbc.sqltiming记录器应该足以指出问题所在,然后如果需要,您可以使用其他选项进行深入研究。但这听起来可以破解它以获得结果集计数。

于 2013-11-06T23:08:37.443 回答
0

Hibernate 是一个非常复杂的框架。如您所见,与原始 JDBC 相比,它消耗了大量的整体执行时间。而且您的查询不一定会创建 1111 个对象,因为 Hibernate 利用缓存、二级缓存和其他黑暗技术来代理对象并节省一些内存,这当然取决于配置。

但是,如果您正在寻找从 Java 代码中计算某些统计信息的任何方法,您应该使用 Hibernate Statistics,它们在某些情况下非常有用,确定它们不适合您吗?

QueryStatistics queryStats = stats.getQueryStatistics("from Store s");
queryStats.getCacheHitCount();
queryStats.getCacheMissCount();
queryStats.getCachePutCount();
queryStats.getExecutionCount();
queryStats.getExecutionAvgTime();
queryStats.getExecutionMaxTime();
queryStats.getExecutionMinTime();
queryStats.getExecutionRowCount();

SecondLevelCacheStatistics cacheStats = stats.getSecondLevelCacheStatistics("Sale.cache");
cacheStats.getElementCountInMemory();
cacheStats.getElementCountOnDisk();
cacheStats.getEntries();
cacheStats.getHitCount();
cacheStats.getMissCount();
cacheStats.getPutCount();
cacheStats.getSizeInMemory();

CollectionStatistics collectionStats = stats.getCollectionStatistics("Sale.items");
collectionStats.getFetchCount();
collectionStats.getLoadCount();
collectionStats.getRecreateCount();
collectionStats.getRemoveCount();
collectionStats.getUpdateCount();

还有更多选择可以探索http://www.javalobby.org/java/forums/t19807.html

于 2013-11-06T22:37:53.983 回答
-1

行数?“选择计数...”(它不像执行两次。计数执行得更快)列计数?反射。摆弄 Class.getDeclaredMethods();

于 2013-10-28T16:42:50.260 回答