使用 JDBC 滚动策略对表格数据进行分页会导致性能下降吗?
Posted
技术标签:
【中文标题】使用 JDBC 滚动策略对表格数据进行分页会导致性能下降吗?【英文标题】:Is using a JDBC scrolling strategy for paging of tabular data going to result detrimental performance? 【发布时间】:2010-08-09 01:34:35 【问题描述】:我们目前有一个在屏幕上显示页面表格数据的系统,而用户界面中没有任何分页支持。它运行在 Java 1.5 / Spring JDBC / T-SQL 存储过程 / SQLServer 2000 堆栈上。
在结果集中无法跳过行的情况下(SQLServer 2K 不使用动态 SQL 的限制);我正在探索让数据层选择所有行并让 DAO 层滚动跳过的行页面然后只读取一页行的选项。
我的问题是这样的:
与返回所有行的当前状态相比,此更改将获得多少性能提升(在 DB CPU 和 I/O 方面)?
我知道只有一页的数据通过数据库和应用程序之间的线路传输,但我很想知道 DBMS 内部会发生什么。假设查询计划已经被缓存,如果我只想要第 41 页,DBMS 是否会跳过前 40 页结果的处理?
我想我想知道我们是否会产生很大的成本,即使光标会跳过结果集的前 x 页。
【问题讨论】:
【参考方案1】:如果您有一个 BTree(索引、集群或非集群),那么转到页面 X 的唯一方法是知道页面上的一个键并直接查找它。 每个其他意味着“跳过”前 X-1 个页面将不得不遍历从 1 到 X 的所有页面并单独跳过每条记录。 'paged' 字段上的窄索引有助于计数,因为高密度槽(因此窄索引)减少了必须扫描以找到开始第 X 页的行的页数。
【讨论】:
感谢 Remus,我认识到驱动数据访问的游标将不得不跳到对应于第 x 页第一行的行。当我们使用 JDBC 滚动到行 (x * pagesize ) 时,这是否意味着 SQLServer 将从磁盘中读取从第 0 页到第 x-1 页的所有行块? 如果你想跳过 1000 行,SQL 必须在“磁盘”上计算 1000 行,这样它才能找到你感兴趣的行。我说'磁盘'是因为不一定是磁盘访问,它可以缓存在缓冲池中。 谢谢 Remus - 我现在知道了。【参考方案2】:为什么不使用单元测试来获取一些数字。
因此,您从当前设置开始,进行 5 次测试,跳过 0、2、4、6、8 页,看看跳过 8 页和 2 页是否有区别。
那么,一旦有了基线,为什么不使用动态 SQL 并只返回感兴趣的行。
编写另一个测试,看看会发生什么。
然后,有一个选择所有内容但只返回感兴趣的行的存储过程,并为此进行另一个测试。 为您 然后,尝试用 DAO 做过滤的想法进行测试。
很难给出关于最后一个性能影响的任何真实想法,因为有很多我们没有的因素,但我希望存储过程执行的工作越多,执行的速度就越快总的来说,你会去的。
我倾向于发现单元测试有助于了解最佳选择,因为您可以在负载下比较它,看看 CPU 和内存会发生什么变化。您可以衡量任何重要的因素,以确定哪个选项最适合您的设计。
【讨论】:
谢谢詹姆斯,肯定是一种有效的方法。我想我正在寻找一个更理论而不是经验的答案。我想知道即使光标滚动过去,DBMS 是否会真正从行中读取数据。 @bart - 我认为这是因为我的工程背景,但在我做出决定之前,我喜欢数字,但您可能想修改您的答案并在此处添加您的评论,因为这听起来像是真实的问题,其余的只是填充物,IMO。以上是关于使用 JDBC 滚动策略对表格数据进行分页会导致性能下降吗?的主要内容,如果未能解决你的问题,请参考以下文章
坑,MySQL中 order by 与 limit 混用,分页会出现问题!