我有一个相当大的表,大约有 10,000,000 行。 我需要从我的 C# 应用程序中翻阅此表。 我正在使用 NHibernate。 我尝试使用此代码示例:
return session.CreateCriteria(typeof(T))
.SetFirstResult(startId)
.SetMaxResults(pageSize)
.List<T>();
当我执行它时,如果我的 startId 大于 7,000,000,操作最终会超时。 我使用的 pageSize 是 200。我已经在小于 1000 行的小得多的表上使用了这种方法,并且它的工作和执行速度很快。
问题是,在这么大的表上,有没有更好的方法使用 NHibernate 来完成此任务?
您正尝试一次分页 200 行 1000 万行吗?为什么?没有人会翻阅那么多数据。
您需要先过滤数据集,然后对较小的数据集应用TSQL样式分页。 这里有一些有效的方法。只需修改它们,以便通过某种过滤(WHERE 子句、CTE 或派生表)获得少于 1000 万行的数据。
有趣的是你应该提出这个问题,因为我也遇到了同样的问题。我的问题与使用 NHibernate 的分页无关,而更多地与使用直接 T-SQL 相关。
似乎有几个选择。我发现在我的实例中非常有用的是关于分页问题的“这个答案”。它讨论使用“..keyset 驱动的解决方案”,而不是通过使用 ROW_NUMBER() 返回排名结果。我不确定 NHibernate 在这种情况下会使用什么,或者是否可以看到它根据您发出的查询生成的 SQL(我知道您可以在 Hibernate 中使用,但我没有使用过 NHibernate)。 如果您不知道使用 SQL SERVER 返回基于 ROW_NUMBER 的排名结果,那么它非常值得研究。很多人似乎都参考
这篇文章来了解如何进行分页。我看到一些后续帖子不鼓励使用 SET ROWCOUNT,但赞成使用带有动态参数的 TOP - SELECT TOP(@NumOfResults)。 这里有很多关于此问题的帖子,但据我所知,没有关于最佳方法的明确答案。我会密切关注这篇文章,看看其他人的建议。
我也有类似的问题。 如果您从中读取的表不断更新,则更新程序会锁定表的部分内容,从而导致从表中读取超时。 添加SetIsolationLayer(ReadUncommissed)你必须注意,数据可能有点脏。