On Thu, 23 May 2024 at 08:48, a.rybakina <a.rybak...@postgrespro.ru> wrote: > -> Sort (cost=613.48..632.86 rows=7754 width=8) (actual > time=7.612..21.214 rows=77531 loops=1) > Sort Key: broke_down_course.sno, broke_down_course.cno > Sort Method: quicksort Memory: 374kB > -> Seq Scan on broke_down_course (cost=0.00..112.54 > rows=7754 width=8) (actual time=0.016..1.366 rows=7754 loops=1)
> Maybe, my reproduction looks questionable, sorry for that, but I seriously > don't understand why we have so many tuples here in Sort node. This is because of the "mark and restore" that occurs because of the Merge Join. This must happen for joins because every tuple matching the join condition must join to every other tuple that matches the join condition. That means, if you have 3 tuples with the same key on either side, you get 9 rows, not 3 rows. Here's a simple example of the behaviour you describe shrunk down so that it's more easily understandable: create table t(a int); insert into t values(1),(1),(1); set enable_hashjoin=0; set enable_nestloop=0; explain (analyze, costs off) select * from t inner join t t1 on t.a=t1.a; QUERY PLAN ------------------------------------------------------------------------ Merge Join (actual time=0.036..0.038 rows=9 loops=1) Merge Cond: (t.a = t1.a) -> Sort (actual time=0.025..0.025 rows=3 loops=1) Sort Key: t.a Sort Method: quicksort Memory: 25kB -> Seq Scan on t (actual time=0.017..0.018 rows=3 loops=1) -> Sort (actual time=0.007..0.007 rows=7 loops=1) Sort Key: t1.a Sort Method: quicksort Memory: 25kB -> Seq Scan on t t1 (actual time=0.003..0.003 rows=3 loops=1) Note the sort has rows=7 and the Seq Scan on t1 rows=3 and an output of 9 rows. If you look at the code in [1], you can see the restoreMark() calls to achieve this. David [1] https://en.wikipedia.org/wiki/Sort-merge_join