七叶笔记 » 数据库 » postgresql分页数据重复问题的深入理解

postgresql分页数据重复问题的深入理解

三种排序

快速排序

此处可以看到limit 10 offset 10结果中,第三条数据重复了第一页的最后一条: (0,10) | 200 | 1

并且n_int = 200 and c_id = 5这条数据被“遗漏”了。

堆排序

堆排序使用内存: Sort Method: top-N heapsort  Memory: 95kB

当offset从0变成1后,以及变成2后,会发现查询出的10条数据不是有顺序的。

归并排序

减小work_mem使用归并排序的时候,offset从0变成1后以及变成2后,任然有序。

还有一种情况,那就是在查询前面几页的时候会有重复,但是越往后面翻就不会重复了,现在也可以解释清楚。

如果每页10条数据,当offse较小的时候使用的内存较少。当offse不断增大,所耗费的内存也就越多。

可以看到当offset从10增加到1000的时候,使用的内存增加,排序的方法从堆排序变成了归并排序。而归并排序为稳定排序,所以后面的分页不会再有后一页出现前一页数据的情况。

参考资料:PostgreSQL - repeating rows from LIMIT OFFSET

参考资料: LIMIT and OFFSET

结语

1.关于分页重复数据的问题主要是排序字段不唯一并且执行计划走了快速排序和堆排序导致。

2.当排序有重复字段,但是如果查询是归并排序,便不会存在有重复数据的问题。

3.当用重复字段排序,前面的页重复,随着offset的增大导致work_mem不足以后使用归并排序,就不存在重复的数据了。

4.排序和算法的稳定性有关,当执行计划选择不同的排序算法时,返回的结果不一样。

5.处理重复数据的常见手段就是,排序的时候可以在排序字段d_larq(立案日期)后面加上c_bh(唯一字段)来排序。

order by d_larq,c_bh;

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对七叶笔记的支持。

相关文章