Gold_,
Я попытался смоделировать ситуацию. У меня 9.4.1-win64.
DROP TABLE a;
DROP TABLE b;
CREATE TABLE a AS
SELECT id,key
FROM generate_series(1,10) id
JOIN generate_series(1,10) key ON id>=key;
CREATE TABLE b AS SELECT id, repeat('X'::text, (random()*50)::int+100) junk FROM generate_series(1,100) id;
INSERT INTO b VALUES (10, 'xtra');
CREATE INDEX i_a ON a(id);
CREATE INDEX i_b ON b(id);
VACUUM ANALYZE a;
VACUUM ANALYZE b;
RESET ALL;
SET enable_hashjoin TO off;
SET enable_nestloop TO off;
SET enable_sort TO off;
EXPLAIN (analyze)
WITH x AS (
SELECT id FROM a ORDER BY id
)
SELECT *
FROM x JOIN b USING (id);
Этот `EXPLAIN` показывает, что:
-> Sort (cost=10000000002.69..10000000002.83 rows=55 width=4) (actual time=0.074..0.079 rows=64 loops=1)
-> CTE Scan on x (cost=0.00..1.10 rows=55 width=4) (actual time=0.022..0.055 rows=55 loops=1)
Т.е. не смотря на то, что нижний узел вернул 55 записей, сортировка отдала 64. Этот эффект возникает из-за дублирующихся значений, т.е. по “десяточкам” надо пройтись 2 раза. Merge Join Rescan называется.
Надеюсь, что пояснил. Сам лучше стал понимать :)