Ich versuche, die Abfrage zu bekommen jedes Jahr mit einer Zählung der Anzahl der Filme in diesem Jahr, die Castings hatte, die alle nicht männlich waren (für jedes Jahr, zählen Sie die Anzahl der Filme in diesem Jahr, das keine Männer hatte).Langsame Leistung mit NOT IN
Dies sind die Tabellen:
ACTOR (id, fname, lname, gender)
MOVIE (id, name, year)
CASTS (pid, mid, role) -- pid refers to actor id, mid refers to movie id
Dies ist, was ich indiziert (id
für die Tabellen Primärschlüssel sind, so dass sie bereits indiziert, oder so gehe ich davon aus):
CREATE INDEX gender_index on actor(gender);
CREATE INDEX movie_name_index on movie(name);
CREATE INDEX movie_year_index on movie(year);
CREATE INDEX casts_index on casts(pid, mid, role);
CREATE INDEX casts_pid_index on casts(pid);
CREATE INDEX casts_mid_index on casts(mid);
CREATE INDEX casts_role_index on casts(role);
Das ist meine Abfrage:
Die Abfrage dauert ewig (und nie abgeschlossen), also wie kann ich mach das schnell? Hilft das mit Hilfe von NOT EXISTS
, obwohl ich dachte, der Optimizer kümmert sich darum? Muss ich etwas anderes indizieren? Gibt es eine andere Frage, die besser ist? Ich benutze PostgreSQL, wenn dies einen Unterschied macht. Hier
ist die EXPLAIN
:
"GroupAggregate (cost=1512539.61..171886457832.52 rows=61 width=8)"
" Group Key: m.year"
" -> Index Scan using movie_year_index on movie m (cost=1512539.61..171886453988.38 rows=768706 width=8)"
" Filter: (NOT (SubPlan 1))"
" SubPlan 1"
" -> Materialize (cost=1512539.18..1732298.66 rows=1537411 width=4)"
" -> Unique (cost=1512539.18..1718605.60 rows=1537411 width=4)"
" -> Merge Join (cost=1512539.18..1700559.32 rows=7218511 width=4)"
" Merge Cond: (m_1.id = c.mid)"
" -> Index Only Scan using movie_pkey on movie m_1 (cost=0.43..57863.94 rows=1537411 width=4)"
" -> Materialize (cost=1512531.37..1548623.92 rows=7218511 width=4)"
" -> Sort (cost=1512531.37..1530577.65 rows=7218511 width=4)"
" Sort Key: c.mid"
" -> Hash Join (cost=54546.59..492838.95 rows=7218511 width=4)"
" Hash Cond: (c.pid = a.id)"
" -> Seq Scan on casts c (cost=0.00..186246.43 rows=11445843 width=8)"
" -> Hash (cost=35248.91..35248.91 rows=1176214 width=4)"
" -> Seq Scan on actor a (cost=0.00..35248.91 rows=1176214 width=4)"
" Filter: ((gender)::text = 'M'::text)"
Was wie plant die 'EXPLAIN' aussehen? – jmelesky
Hinzugefügt EXPLAIN-Ausgabe. – Jack
1) Anstelle des Bündels von (nicht eindeutigen) Indizes: Definieren Sie einige Primärschlüssel und Fremdschlüssel für die Tabellen. Machen Sie sie NOT NULL wo angemessen. 2) 'Vacuum analysis 'alle beteiligten Tabellen. – joop