Gleichbleibenden SELECT beschleunigen ?

Hallo miteinander

kennt jemand einen weg, wie ich einen select, der sich nicht ändert beschleunigen kann ? Habs mit ner View probiert, hat aber auch nix geändert.

Konkret geht es mir um eine Liste, in nem Versand Programm, die anzeigt, was versandt werden kann.

Mit zusätzlichen indexen hab ich sie schon von 15 auf 3 sekunden herunter gebracht, aber mich würd interessieren, obs da noch weitere Möglichkeiten gibt.

mfg
henrik

Hmm, mal EXPLAIN probiert für diesen Query? Den ein oder anderen Index testweise an passender Stelle hinzugefügt, dann noch mal Explain?

Ansonsten könntest du den Query hier auch mal posten.

Über wieviele Einträge in der Tabelle läuft der Query?

ja hab ich auch schon gemacht, aber irgendwie werd ich nicht ganz schlau daraus, was ist schneller ein hash join, nested loop, wie kann ich da was verbessern usw.

hier mal der EXPLAIN von meinem select

"Sort (cost=48737.56..48737.68 rows=48 width=151)"
" Sort Key: min(a.express), min(a.eingang_am)"
" -> HashAggregate (cost=48731.66..48736.22 rows=48 width=151)"
"  Filter: ((sum(anzahl) >= sum(anzahl)) OR (min(teillieferung) = 1))"
"  -> Nested Loop Left Join (cost=22531.66..48729.62 rows=48 width=151)"
"    Join Filter: (("inner".anzahl >= "outer".anzahl) OR ("outer".teillieferung IS NOT NULL))"
"    -> Nested Loop Left Join (cost=22531.66..48521.03 rows=48 width=151)"
"     -> Hash Join (cost=22531.66..48374.04 rows=48 width=134)"
"       Hash Cond: (("outer".adresse_id)::bpchar = "inner".adresse_id_lief)"
"       -> Seq Scan on adresse adr (cost=0.00..22541.60 rows=660060 width=42)"
"       -> Hash (cost=22531.54..22531.54 rows=48 width=164)"
"        -> Hash Join (cost=13899.27..22531.54 rows=48 width=164)"
"          Hash Cond: (("outer".auftrag_id)::bpchar = "inner".auftrag_id)"
"          -> Index Scan using a_status_id on auftrag a (cost=0.00..8563.22 rows=9143 width=34)"
"           Index Cond: (status_id < 170)"
"          -> Hash (cost=13897.11..13897.11 rows=867 width=188)"
"           -> Nested Loop (cost=1528.61..13897.11 rows=867 width=188)"
"             -> Nested Loop (cost=1528.61..11273.57 rows=867 width=116)"
"              -> Nested Loop (cost=1528.61..6402.55 rows=874 width=101)"
"                -> Hash Join (cost=1528.61..3721.51 rows=886 width=134)"
"                 Hash Cond: (("outer".auftragpos_id)::text = ("inner".auftragpos_id)::text)"
"                 -> Seq Scan on prodjob pj (cost=0.00..1673.02 rows=51102 width=112)"
"                 -> Hash (cost=1521.04..1521.04 rows=3029 width=22)"
"                   -> Bitmap Heap Scan on auftragpos_prod app (cost=22.60..1521.04 rows=3029 width=22)"
"                    Recheck Cond: (((prodstatus_id)::text = '150'::text) OR ((prodstatus_id)::text = '160'::text))"
"                    -> BitmapOr (cost=22.60..22.60 rows=3029 width=0)"
"                      -> Bitmap Index Scan on app_prodstatus_id (cost=0.00..20.60 rows=3029 width=0)"
"                       Index Cond: ((prodstatus_id)::text = '150'::text)"
"                      -> Bitmap Index Scan on app_prodstatus_id (cost=0.00..2.00 rows=1 width=0)"
"                       Index Cond: ((prodstatus_id)::text = '160'::text)"
"                -> Index Scan using auftragpos_pkey on auftragpos ap (cost=0.00..3.01 rows=1 width=25)"
"                 Index Cond: (("outer".auftragpos_id)::text = (ap.auftragpos_id)::text)"
"                 Filter: (storniert IS NULL)"
"              -> Index Scan using lp_auftragpos_id on lieferpos lp (cost=0.00..5.56 rows=1 width=72)"
"                Index Cond: (("outer".auftragpos_id)::bpchar = lp.auftragpos_id)"
"                Filter: (anzahl <> anzahl_ist)"
"             -> Index Scan using liefer_pkey on liefer l (cost=0.00..3.01 rows=1 width=108)"
"              Index Cond: (l.liefer_id = "outer".liefer_id)"
"     -> Index Scan using versandlager_fach_pkey on versandlager_fach vlf (cost=0.00..3.05 rows=1 width=53)"
"       Index Cond: (("outer".versandlager_fach_id)::text = (vlf.versandlager_fach_id)::text)"
"    -> Index Scan using prodjob_status_pkey on prodjob_status pjs (cost=0.00..4.33 rows=1 width=40)"
"     Index Cond: (((pjs.prodjob_status_id)::text = '250'::text) AND ((pjs.prodjob_id)::text = ("outer".prodjob_id)::text))"

Args, kannst du da mal ein Code Tag drumherum setzen, damit er das vernünftig einrückt. So, wie die Ausgabe in der psql Shell auch zu sehen ist.
Versuch mal mit der Vorschaufunktion, ob du das so hinbekommst, aus dem Chaos da oben kann man sich schlecht zusammenrechnen, was nun wozu gehört, sorry.

@henrik: das aussehen solltest du wirklich noch mal überarbeiten. hab jetzt mal zumindest die code tags rein gemacht :wink:

wenn ich das richtig sehe scheint

min(a.express), min(a.eingang_am)

dich scho mal gewaltig zu bremsen. auf den feldern ein index droben?

ansonsten schau ich mal wenn du das nochmals überarbeitet hast :wink:

cu tb.

Kannst du den Query hier ev. auch posten?

die query darf ich leider nicht posten sorry :frowning:

Du kannst z.B. auch die Spaltennamen und Tabellennamen verändern, wenn dir das hilft. Der Explain Output ist ohne Query aber etwas zu komplex, um hier bessere Aussagen als die von Xandrian treffen zu können …

hier ist mein select

 
SELECT max((((vlf.abteilung::text || '-'::text) || vlf.etage_nr::text) || '-'::text) || vlf.fach_nr::text) AS fach, (sum(pjs.anzahl)::text || '/'::text) || sum(ap.anzahl)::text AS buchanzahl, max(vlf.versandlager_fach_id::text) AS versandlager_fach_id, min(pj.prodjob_id::text) AS prodjob_id, 
        CASE
            WHEN min(a.teillieferung) = 1 THEN 'JA'::text
            ELSE NULL::text
        END AS teil, 
        CASE
            WHEN min(a.teillieferung) = 1 THEN 'JA'::text
            ELSE NULL::text
        END AS t, min(a.eingang_am) AS eingang_am, COALESCE(min(vlf.markiert)::text, ''::text) AS markiert, 
        CASE
            WHEN COALESCE(min(a.express)::integer, 0) = 1 THEN 'JA'::text
            ELSE ''::text
        END AS express, 
        CASE
            WHEN COALESCE(min(a.express)::integer, 0) = 1 THEN 'JA'::text
            ELSE ''::text
        END AS e, 
        CASE
            WHEN min(adr.land_id::text) = '241'::text THEN ''::text
            ELSE 'JA'::text
        END AS ausland
   FROM liefer l
   JOIN adresse adr ON l.adresse_id_lief = adr.adresse_id::bpchar
   JOIN lieferpos lp ON l.liefer_id = lp.liefer_id AND lp.anzahl <> lp.anzahl_ist
   JOIN auftrag a ON a.auftrag_id::bpchar = l.auftrag_id AND a.status_id < 170 AND a.status_id >= 100
   JOIN auftragpos ap ON ap.auftragpos_id::bpchar = lp.auftragpos_id AND ap.storniert IS NULL
   JOIN prodjob pj ON pj.auftragpos_id::text = ap.auftragpos_id::text
   JOIN auftragpos_prod app ON app.auftragpos_id::text = ap.auftragpos_id::text AND (app.prodstatus_id::text = '150'::text OR app.prodstatus_id::text = '160'::text)
   LEFT JOIN versandlager_fach vlf ON pj.versandlager_fach_id::text = vlf.versandlager_fach_id::text
   LEFT JOIN prodjob_status pjs ON pjs.prodjob_id::text = pj.prodjob_id::text AND pjs.prodjob_status_id::text = '250'::text AND (pjs.anzahl >= pj.anzahl OR a.teillieferung IS NOT NULL)
  WHERE l.ausgeliefert_am IS NULL
  GROUP BY l.liefer_id
 HAVING sum(pjs.anzahl) >= sum(ap.anzahl) OR min(a.teillieferung) = 1
  ORDER BY min(a.express) DESC, min(a.eingang_am);

und hier noch ein explain analyze

"Sort (cost=46332.28..46332.29 rows=1 width=151) (actual time=44242.069..44242.148 rows=50 loops=1)"
" Sort Key: min(a.express), min(a.eingang_am)"
" -> HashAggregate (cost=46332.18..46332.27 rows=1 width=151) (actual time=44235.862..44241.597 rows=50 loops=1)"
"  Filter: ((sum(anzahl) >= sum(anzahl)) OR (min(teillieferung) = 1))"
"  -> Nested Loop Left Join (cost=20473.65..46332.13 rows=1 width=151) (actual time=35703.979..44182.026 rows=2335 loops=1)"
"    Join Filter: (("inner".anzahl >= "outer".anzahl) OR ("outer".teillieferung IS NOT NULL))"
"    -> Nested Loop Left Join (cost=20473.65..46327.79 rows=1 width=151) (actual time=35695.509..40791.609 rows=2335 loops=1)"
"     -> Hash Join (cost=20473.65..46324.73 rows=1 width=134) (actual time=35695.494..40704.780 rows=2335 loops=1)"
"       Hash Cond: (("outer".adresse_id)::bpchar = "inner".adresse_id_lief)"
"       -> Seq Scan on adresse adr (cost=0.00..22547.71 rows=660671 width=42) (actual time=0.090..3031.903 rows=660683 loops=1)"
"       -> Hash (cost=20473.65..20473.65 rows=1 width=164) (actual time=35695.242..35695.242 rows=2335 loops=1)"
"        -> Hash Join (cost=13952.73..20473.65 rows=1 width=164) (actual time=35362.055..35681.520 rows=2335 loops=1)"
"          Hash Cond: (("outer".auftrag_id)::bpchar = "inner".auftrag_id)"
"          -> Index Scan using a_status_id on auftrag a (cost=0.00..6475.18 rows=6097 width=34) (actual time=0.129..292.460 rows=4947 loops=1)"
"           Index Cond: ((status_id < 170) AND (status_id >= 100))"
"          -> Hash (cost=13952.69..13952.69 rows=18 width=188) (actual time=35361.877..35361.877 rows=2335 loops=1)"
"           -> Nested Loop (cost=1528.61..13952.69 rows=18 width=188) (actual time=460.851..35338.912 rows=2335 loops=1)"
"             -> Nested Loop (cost=1528.61..11295.86 rows=878 width=116) (actual time=430.211..22367.539 rows=2336 loops=1)"
"              -> Nested Loop (cost=1528.61..6402.55 rows=878 width=101) (actual time=393.409..967.879 rows=2357 loops=1)"
"                -> Hash Join (cost=1528.61..3721.51 rows=886 width=134) (actual time=393.195..716.505 rows=2361 loops=1)"
"                 Hash Cond: (("outer".auftragpos_id)::text = ("inner".auftragpos_id)::text)"
"                 -> Seq Scan on prodjob pj (cost=0.00..1673.02 rows=51102 width=112) (actual time=0.036..163.320 rows=50999 loops=1)"
"                 -> Hash (cost=1521.04..1521.04 rows=3029 width=22) (actual time=392.432..392.432 rows=3470 loops=1)"
"                   -> Bitmap Heap Scan on auftragpos_prod app (cost=22.60..1521.04 rows=3029 width=22) (actual time=18.294..380.614 rows=3470 loops=1)"
"                    Recheck Cond: (((prodstatus_id)::text = '150'::text) OR ((prodstatus_id)::text = '160'::text))"
"                    -> BitmapOr (cost=22.60..22.60 rows=3029 width=0) (actual time=17.389..17.389 rows=0 loops=1)"
"                      -> Bitmap Index Scan on app_prodstatus_id (cost=0.00..20.60 rows=3029 width=0) (actual time=17.297..17.297 rows=3436 loops=1)"
"                       Index Cond: ((prodstatus_id)::text = '150'::text)"
"                      -> Bitmap Index Scan on app_prodstatus_id (cost=0.00..2.00 rows=1 width=0) (actual time=0.083..0.083 rows=37 loops=1)"
"                       Index Cond: ((prodstatus_id)::text = '160'::text)"
"                -> Index Scan using auftragpos_pkey on auftragpos ap (cost=0.00..3.01 rows=1 width=25) (actual time=0.094..0.097 rows=1 loops=2361)"
"                 Index Cond: (("outer".auftragpos_id)::text = (ap.auftragpos_id)::text)"
"                 Filter: (storniert IS NULL)"
"              -> Index Scan using lp_auftragpos_id on lieferpos lp (cost=0.00..5.56 rows=1 width=72) (actual time=8.997..9.069 rows=1 loops=2357)"
"                Index Cond: (("outer".auftragpos_id)::bpchar = lp.auftragpos_id)"
"                Filter: (anzahl <> anzahl_ist)"
"             -> Index Scan using liefer_pkey on liefer l (cost=0.00..3.01 rows=1 width=108) (actual time=5.538..5.541 rows=1 loops=2336)"
"              Index Cond: (l.liefer_id = "outer".liefer_id)"
"              Filter: (ausgeliefert_am IS NULL)"
"     -> Index Scan using versandlager_fach_pkey on versandlager_fach vlf (cost=0.00..3.05 rows=1 width=53) (actual time=0.027..0.028 rows=0 loops=2335)"
"       Index Cond: (("outer".versandlager_fach_id)::text = (vlf.versandlager_fach_id)::text)"
"    -> Index Scan using prodjob_status_pkey on prodjob_status pjs (cost=0.00..4.33 rows=1 width=40) (actual time=1.443..1.443 rows=0 loops=2335)"
"     Index Cond: (((pjs.prodjob_status_id)::text = '250'::text) AND ((pjs.prodjob_id)::text = ("outer".prodjob_id)::text))"