hibernate生成的以下查询将花费13+秒并锁定表:
SELECT COUNT(auditentit0_.audit_id) AS col_0_0_ FROM Audit auditentit0_ WHERE 1=1;
不断增长的Microsoft SQL Server数据库表包含90+百万行。
对于Microsoft SQL Server,我发现了一种非常快速地获取相同信息的准确元数据方法。
但是,如果休眠模式可以获取此信息,我宁愿不为Microsoft sql服务器和oracle(下一个数据库)编写自定义代码。
这是一个准确且几乎即时的Microsoft sql服务器元数据查询示例:
SELECT SUM (row_count) FROM sys.dm_db_partition_stats WHERE object_id=OBJECT_ID('huge_audit_table') AND (index_id=0 or index_id=1);
有没有办法让休眠模式对表行计数发出类似的查询?
一个发布的答案表明一个视图可能有用。我正在调查此帖子,看它是否可以解决问题:
https://vladmihalcea.com/map-jpa-entity-to-view-or-sql-query-with-hibernate/
答案 0 :(得分:1)
在休眠模式下,您应该在提供的链接中使用投影,以确保它可以在多个dbms上使用:
protected Long countByCriteria(DetachedCriteria criteria) {
Criteria crit = criteria.getExecutableCriteria(getSession());
crit.setProjection(Projections.rowCount());
return (Long)crit.uniqueResult();
}
您在mysql中使用什么引擎?我从未在MySql或Oracle中遇到过行计数阻塞的问题。也许以下链接会为您提供帮助:Any way to select without causing locking in MySQL?
此外,在快速阅读后,我看到Sql Server确实确实在计数上受阻。
也许您可以使用存储过程或其他机制将问题传递给dbms。
编辑:
Hibernate中的投影用于选择要提取的列,用于对元素进行分组的列以及使用内置的聚合函数(求和,计数,平均,最大值,最小值,计数区别)。
它可帮助您保持应用程序数据库不可知。请记住,hibernate支持大约30个数据库。
在您的情况下,mssql有一个特定的问题,因为计数会阻塞表的优先级。估计后,使用系统视图确实非常快捷,但这不是标准的。
您可以将问题封装到依赖于视图或存储过程的dbms中。或者,也许您可以尝试使用NOLOCK提示或在休眠状态下使用READ UNCOMMITED(在审计表计数中应该可以接受)。
答案 1 :(得分:0)
为解决此特定问题,我们后退并更改了UI的功能。通过UIX和UI开发人员之间的共同努力,我们同意未过滤的查询不会要求总数。初始屏幕加载将仅显示充满数据的页面。没有60,000个控件的第1页。仅当用户输入特定条件时,总数才起作用。这些查询应该很快。现在,用户仍然可以设置与原始问题一样糟糕的查询。相对于规范应该是例外。
因此,对于OP确实没有可靠的答案。如果您遇到此类问题,并且可以控制UI和API,那么现在该重新考虑解决方案了。从UI角度考虑google如何处理分页。恕我直言,显示“第(XX)页1”的日子已经过去。