PgSQL外连接分页时出现重复数据

今天工作中遇到的问题。

SELECT * FROM a LEFT JOIN b
	ON a.c = b.d
	LIMIT 20 OFFSET 0;

SELECT * FROM a LEFT JOIN b
	ON a.c = b.d
	LIMIT 20 OFFSET 20;

上面两条是一摸一样的语句,只有OFFSET参数不同,相当于第一条语句显示出第一页的数据,第二条显示出第二页,页大小为20,不同的两页理应不应该有重复数据,但确实出现了。

但当我把公司的两张表弄到我的pgsql上,问题就没了

公司PGSQL版本:12.2
我的PGSQL版本:14.5

最开始怀疑的方向错了,看到版本不同表现不同,就怀疑是优化器的锅了。

img

果然,offset为0和offset为20时所使用的执行计划不同,offset为0时被转成了Right Join,而高版本就没这个问题。

按理来说,Right Join和Left Join也不应该造成结果有差异,因为都是双层循环,主表(在这个例子中是a)在外层循环中。但关键是这个用的又是什么Hash Join。我之前没了解过(好像数据库系统里学过),不过应该是Hash Join使得左右连接产生了不同的结果。

解决办法#

  1. 添加Order by确定排序顺序
  2. 关闭hashjoin
  3. 不知道PgSQL有没有索引提示这种东西,如果有的话可以影响执行计划的选择
posted @   yudoge  阅读(378)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
主题色彩