I have very simple query which uses json data for joining on primary table:
WITH timecode_range AS ( SELECT (t->>'table_id')::integer AS table_id, (t->>'timecode_from')::bigint AS timecode_from, (t->>'timecode_to')::bigint AS timecode_to FROM (SELECT '{"table_id":1,"timecode_from":19890328,"timecode_to":119899328}'::jsonb t) rowset ) SELECT n.* FROM partition.json_notification n INNER JOIN timecode_range r ON n.table_id = r.table_id AND n.timecode > r.timecode_from AND n.timecode <= r.timecode_to It works perfectly when "timecode_range" returns only 1 record:
Nested Loop (cost=0.43..4668.80 rows=1416 width=97) (actual time=0.352..0.352 rows=0 loops=1) CTE timecode_range -> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1) -> CTE Scan on timecode_range r (cost=0.00..0.02 rows=1 width=20) (actual time=0.007..0.007 rows=1 loops=1) -> Index Scan using json_notification_pkey on json_notification n (cost=0.42..4654.61 rows=1416 width=97) (actual time=0.322..0.322 rows=0 loops=1) Index Cond: ((timecode > r.timecode_from) AND (timecode <= r.timecode_to)) Filter: (r.table_id = table_id) Planning time: 2.292 ms Execution time: 0.665 ms But when I need to return several records:
WITH timecode_range AS ( SELECT (t->>'table_id')::integer AS table_id, (t->>'timecode_from')::bigint AS timecode_from, (t->>'timecode_to')::bigint AS timecode_to FROM (SELECT json_array_elements('[{"table_id":1,"timecode_from":19890328,"timecode_to":119899328}]') t) rowset ) SELECT n.* FROM partition.json_notification n INNER JOIN timecode_range r ON n.table_id = r.table_id AND n.timecode > r.timecode_from AND n.timecode <= r.timecode_to It starts using sequential scan and execution time dramatically grows :(
Hash Join (cost=7.01..37289.68 rows=92068 width=97) (actual time=418.563..418.563 rows=0 loops=1) Hash Cond: (n.table_id = r.table_id) Join Filter: ((n.timecode > r.timecode_from) AND (n.timecode <= r.timecode_to)) Rows Removed by Join Filter: 14444 CTE timecode_range -> Subquery Scan on rowset (cost=0.00..3.76 rows=100 width=32) (actual time=0.233..0.234 rows=1 loops=1) -> Result (cost=0.00..0.51 rows=100 width=0) (actual time=0.218..0.218 rows=1 loops=1) -> Seq Scan on json_notification n (cost=0.00..21703.36 rows=840036 width=97) (actual time=0.205..312.991 rows=840036 loops=1) -> Hash (cost=2.00..2.00 rows=100 width=20) (actual time=0.239..0.239 rows=1 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> CTE Scan on timecode_range r (cost=0.00..2.00 rows=100 width=20) (actual time=0.235..0.236 rows=1 loops=1) Planning time: 4.729 ms Execution time: 418.937 ms What am I doing wrong?