add batch remove batch split batch comment selection show hidden batches hide batch highlight batch
db<>fiddle
donate feedback about
By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
Help with an interesting Postgres question: Why isn't an Index Only Scan used on a partition accessed via the parent table?.
CREATE SEQUENCE actor_actor_id_seq
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;

CREATE TABLE actor (
actor_id integer DEFAULT nextval('actor_actor_id_seq'::regclass) NOT NULL,
first_name character varying(45) NOT NULL,
last_name character varying(45) NOT NULL,
last_update timestamp without time zone DEFAULT now() NOT NULL
);

CREATE SEQUENCE film_film_id_seq
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;

CREATE TABLE film (
film_id integer DEFAULT nextval('film_film_id_seq'::regclass) NOT NULL,
title character varying(255) NOT NULL,
last_update timestamp without time zone DEFAULT now() NOT NULL
);

CREATE TABLE film_actor (
actor_id smallint NOT NULL,
film_id smallint NOT NULL,
last_update timestamp without time zone DEFAULT now() NOT NULL
);

ALTER TABLE ONLY actor
ADD CONSTRAINT actor_pkey PRIMARY KEY (actor_id);
ALTER TABLE ONLY film
ADD CONSTRAINT film_pkey PRIMARY KEY (film_id);
ALTER TABLE ONLY film_actor
CREATE SEQUENCE
CREATE TABLE
CREATE SEQUENCE
CREATE TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
CREATE INDEX
CREATE INDEX
INSERT 0 200
INSERT 0 1000
INSERT 0 5462
vacuum analyze;
VACUUM
explain analyze
select film.film_id, film.title, a.actors
from film
left join
(
select film_actor.film_id, array_agg(first_name) as actors
from actor
inner join film_actor using(actor_id)
group by film_actor.film_id
) as a
on a.film_id = film.film_id
where film.title = 'ACADEMY DINOSAUR'
order by film.title;
QUERY PLAN
Merge Left Join (cost=453.12..519.03 rows=1 width=51) (actual time=2.994..2.995 rows=1 loops=1)
  Merge Cond: (film.film_id = film_actor.film_id)
  -> Sort (cost=8.30..8.31 rows=1 width=19) (actual time=0.196..0.196 rows=1 loops=1)
        Sort Key: film.film_id
        Sort Method: quicksort Memory: 25kB
        -> Index Scan using idx_title on film (cost=0.28..8.29 rows=1 width=19) (actual time=0.013..0.016 rows=1 loops=1)
              Index Cond: ((title)::text = 'ACADEMY DINOSAUR'::text)
  -> GroupAggregate (cost=444.82..498.25 rows=997 width=34) (actual time=2.791..2.792 rows=1 loops=1)
        Group Key: film_actor.film_id
        -> Sort (cost=444.82..458.47 rows=5462 width=8) (actual time=2.771..2.772 rows=11 loops=1)
              Sort Key: film_actor.film_id
              Sort Method: quicksort Memory: 449kB
              -> Hash Join (cost=6.50..105.76 rows=5462 width=8) (actual time=0.093..1.698 rows=5462 loops=1)
                    Hash Cond: (film_actor.actor_id = actor.actor_id)
                    -> Seq Scan on film_actor (cost=0.00..84.62 rows=5462 width=4) (actual time=0.008..0.405 rows=5462 loops=1)
                    -> Hash (cost=4.00..4.00 rows=200 width=10) (actual time=0.064..0.064 rows=200 loops=1)
                          Buckets: 1024 Batches: 1 Memory Usage: 17kB
                          -> Seq Scan on actor (cost=0.00..4.00 rows=200 width=10) (actual time=0.006..0.031 rows=200 loops=1)
Planning time: 2.546 ms
Execution time: 3.315 ms
EXPLAIN
explain analyze
select film.film_id, film.title, a.actors
from film
left join lateral
(
select array_agg(first_name) as actors
from actor
inner join film_actor using(actor_id)
where film_actor.film_id = film.film_id
) as a
on true
where film.title = 'ACADEMY DINOSAUR'
order by film.title;
QUERY PLAN
Nested Loop Left Join (cost=23.15..31.20 rows=1 width=51) (actual time=0.544..0.546 rows=1 loops=1)
  -> Index Scan using idx_title on film (cost=0.28..8.29 rows=1 width=19) (actual time=0.012..0.013 rows=1 loops=1)
        Index Cond: ((title)::text = 'ACADEMY DINOSAUR'::text)
  -> Aggregate (cost=22.87..22.88 rows=1 width=32) (actual time=0.530..0.530 rows=1 loops=1)
        -> Hash Join (cost=18.32..22.86 rows=5 width=6) (actual time=0.467..0.518 rows=10 loops=1)
              Hash Cond: (actor.actor_id = film_actor.actor_id)
              -> Seq Scan on actor (cost=0.00..4.00 rows=200 width=10) (actual time=0.007..0.023 rows=200 loops=1)
              -> Hash (cost=18.26..18.26 rows=5 width=2) (actual time=0.415..0.415 rows=10 loops=1)
                    Buckets: 1024 Batches: 1 Memory Usage: 9kB
                    -> Bitmap Heap Scan on film_actor (cost=4.32..18.26 rows=5 width=2) (actual time=0.380..0.401 rows=10 loops=1)
                          Recheck Cond: (film_id = film.film_id)
                          Heap Blocks: exact=10
                          -> Bitmap Index Scan on idx_fk_film_id (cost=0.00..4.32 rows=5 width=0) (actual time=0.320..0.320 rows=10 loops=1)
                                Index Cond: (film_id = film.film_id)
Planning time: 0.739 ms
Execution time: 0.631 ms
EXPLAIN
explain analyze
select film.film_id, film.title, array_agg(a.first_name) as actors
from film
left join
(
select film_actor.film_id, actor.first_name
from actor
inner join film_actor using(actor_id)
) as a
on a.film_id = film.film_id
where film.title = 'ACADEMY DINOSAUR'
group by film.film_id, film.title
order by film.title;
QUERY PLAN
GroupAggregate (cost=29.44..29.49 rows=1 width=51) (actual time=0.158..0.160 rows=1 loops=1)
  Group Key: film.film_id
  -> Sort (cost=29.44..29.45 rows=5 width=25) (actual time=0.144..0.147 rows=10 loops=1)
        Sort Key: film.film_id
        Sort Method: quicksort Memory: 25kB
        -> Nested Loop Left Join (cost=4.74..29.38 rows=5 width=25) (actual time=0.074..0.133 rows=10 loops=1)
              -> Index Scan using idx_title on film (cost=0.28..8.29 rows=1 width=19) (actual time=0.033..0.034 rows=1 loops=1)
                    Index Cond: ((title)::text = 'ACADEMY DINOSAUR'::text)
              -> Nested Loop (cost=4.47..19.09 rows=200 width=8) (actual time=0.039..0.094 rows=10 loops=1)
                    -> Bitmap Heap Scan on film_actor (cost=4.32..18.26 rows=5 width=4) (actual time=0.028..0.042 rows=10 loops=1)
                          Recheck Cond: (film_id = film.film_id)
                          Heap Blocks: exact=10
                          -> Bitmap Index Scan on idx_fk_film_id (cost=0.00..4.32 rows=5 width=0) (actual time=0.022..0.022 rows=10 loops=1)
                                Index Cond: (film_id = film.film_id)
                    -> Index Scan using actor_pkey on actor (cost=0.14..0.17 rows=1 width=10) (actual time=0.004..0.004 rows=1 loops=10)
                          Index Cond: (actor_id = film_actor.actor_id)
Planning time: 0.739 ms
Execution time: 0.247 ms
EXPLAIN
explain analyze
select film.film_id, film.title, array_agg(a.first_name) as actors
from film
left join lateral
(
select actor.first_name
from actor
inner join film_actor using(actor_id)
where film_actor.film_id = film.film_id
) as a
on true
where film.title = 'ACADEMY DINOSAUR'
group by film.film_id, film.title
order by film.title;
QUERY PLAN
GroupAggregate (cost=29.44..29.49 rows=1 width=51) (actual time=0.076..0.077 rows=1 loops=1)
  Group Key: film.film_id
  -> Sort (cost=29.44..29.45 rows=5 width=25) (actual time=0.070..0.071 rows=10 loops=1)
        Sort Key: film.film_id
        Sort Method: quicksort Memory: 25kB
        -> Nested Loop Left Join (cost=4.74..29.38 rows=5 width=25) (actual time=0.036..0.064 rows=10 loops=1)
              -> Index Scan using idx_title on film (cost=0.28..8.29 rows=1 width=19) (actual time=0.008..0.009 rows=1 loops=1)
                    Index Cond: ((title)::text = 'ACADEMY DINOSAUR'::text)
              -> Nested Loop (cost=4.47..19.09 rows=200 width=8) (actual time=0.027..0.052 rows=10 loops=1)
                    -> Bitmap Heap Scan on film_actor (cost=4.32..18.26 rows=5 width=4) (actual time=0.019..0.026 rows=10 loops=1)
                          Recheck Cond: (film_id = film.film_id)
                          Heap Blocks: exact=10
                          -> Bitmap Index Scan on idx_fk_film_id (cost=0.00..4.32 rows=5 width=0) (actual time=0.015..0.015 rows=10 loops=1)
                                Index Cond: (film_id = film.film_id)
                    -> Index Scan using actor_pkey on actor (cost=0.14..0.17 rows=1 width=10) (actual time=0.002..0.002 rows=1 loops=10)
                          Index Cond: (actor_id = film_actor.actor_id)
Planning time: 0.339 ms
Execution time: 0.131 ms
EXPLAIN