Performance Optimierung von UNION Statements

Fragen und Probleme rund um die Abfragespache SQL.
Antworten
moehre
Neuer Benutzer
Beiträge: 7
Registriert: Mi 8. Feb 2017, 12:53

Performance Optimierung von UNION Statements

Beitrag von moehre » Do 10. Mai 2018, 19:03

Hallo Zusammen,

ich habe ein SQL-Statment mit mehreren UNION-Befehlen.
Diese UNION Befehle besitzen mehrere JOINs. Kann ich die JOINS, die in allen vorkommen, auch am Ende einmalig aufrufen???
Dann würde ich ja deutlich Performancesteigerungen haben. Und momentan dauert es leider ewig...

Query:

Code: Alles auswählen

SET SEARCH_PATH TO public, "test";


SELECT *

FROM     (SELECT a.link_id AS LinkID,  GREATEST(a.From_Ref_Speed_Limit, a.To_Ref_Speed_Limit) as SpeedLimit,            

                CASE WHEN a.speed_limit_source = '1' THEN 1 WHEN a.speed_limit_source = '2' THEN 2 ELSE 0 

                END as LegalType, 0 as LimitType, 0 as vehicletype, '' as timedomain

                FROM rdf_nav_link a ) AS A1

WHERE SpeedLimit is not null 


UNION ALL


SELECT *

FROM     (SELECT a.link_id AS LinkID, d.special_speed_limit AS SpeedLimit, 1 AS LegalType,

                CASE WHEN d.dependent_speed_type = 1 THEN 1 WHEN d.dependent_speed_type = 2 THEN 2 WHEN d.dependent_speed_type = 3 THEN 3 WHEN d.dependent_speed_type = 7 THEN 4 ELSE 0 END as LimitType, CASE WHEN g.automobiles = 'Y' AND g.trucks = 'Y' AND g.motorcycles = 'Y' THEN 0 WHEN g.automobiles = 'Y' AND g.trucks = 'N' AND g.motorcycles = 'N' THEN 1 WHEN g.automobiles = 'N' AND g.trucks = 'Y' AND g.motorcycles = 'N' THEN 2 WHEN g.automobiles = 'N' AND g.trucks = 'N' AND g.motorcycles = 'Y' THEN 3 ELSE 0 END as vehicleTypes,CASE WHEN d.dependent_speed_type = 4 THEN (SELECT t.time_domain FROM rdf_time_domain t WHERE d.condition_id = t.feature_id) ELSE '' END as timedomain
 
		FROM rdf_nav_link a

                JOIN rdf_nav_strand l ON a.link_id = l.link_id

                JOIN rdf_condition f ON l.nav_strand_id = f.nav_strand_id

                JOIN rdf_condition_speed d ON f.condition_id = d.condition_id AND d.special_speed_limit IS NOT NULL

                JOIN rdf_access g ON f.access_id = g.access_id) AS A2


UNION ALL


SELECT *

FROM     (SELECT a.link_id AS LinkID, 0 AS SpeedLimit, 1 AS LegalType,5 as LimitType,CASE WHEN g.automobiles = 'Y' AND g.trucks = 'Y' AND g.motorcycles = 'Y' THEN 0 WHEN g.automobiles = 'Y' AND g.trucks = 'N' AND g.motorcycles = 'N' THEN 1 WHEN g.automobiles = 'N' AND g.trucks = 'Y' AND g.motorcycles = 'N' THEN 2 WHEN g.automobiles = 'N' AND g.trucks = 'N' AND g.motorcycles = 'Y' THEN 3 ELSE 0 END as vehicleTypes,'' as timedomain
                
                FROM rdf_nav_link a

                JOIN rdf_nav_strand l ON a.link_id = l.link_id

                JOIN rdf_condition f ON l.nav_strand_id = f.nav_strand_id AND f.condition_type = 11

                JOIN rdf_access g ON f.access_id = g.access_id) AS A3
     

ORDER BY LinkID

pogomips
Benutzer
Beiträge: 58
Registriert: Fr 18. Nov 2016, 09:55

Re: Performance Optimierung von UNION Statements

Beitrag von pogomips » Do 10. Mai 2018, 21:03

Ja, kannst Du machen, kein Problem.
Ob das "eine enorme Performancesteigerung" ergibt, ist aber von außen betrachtet nicht vorhersagbar.
Angenommen:
alle 3 Selects sind gleich schnell(langsam)
Ursache sind die besagten joins

Derzeit werden sie 3x ausgeführt
hast Du theoretisch einen Gewinn von Faktor 3

Bei sehr langen Ausführungszeiten kann das viel sein, aber immer noch lahm
bei kurzen Ausführungszeiten (msec Bereich) macht es keinen Unterschied.

Der Punkt ist, diese Joins sind nicht die einzigen Faktoren im Statement. Ganz entscheidend bei Union ist die gesamte Datenmenge, die "Qualität" der Einzelselect und die Größe der Ergebnismenge.

Wenn Du auf ein paar Mio Datensätzen arbeitests, sagen wir 3 Mio ergibt das Union All dann eben 9 Mio. Diese Datenmenge muss "künstlich" aufgebaut und bereitgehalten werden. Allein das Erstellen (Anhäufen) kostet eine Menge Ressourcen, unabhängig von der Geschwindigkeit beim Zusammensuchen.
Das ist natürlich ein Worst-Case Beispiel. Ist die Ergebnismenge, auch im Union klein, paar Hundert oder Tausend DS, besteht das Problem natürlich nicht. Dann ist die Geschwindigkeit beim Finden entscheidend. Hier wäre erstmal die Frage, ob die Einzelstatements schnell laufen (wie schnell) und ob es für sich optimierbar ist.

Also einmal Ausführungsplan / Mengengerüste gesamt/ eingeschränkt für alle 3 bitte posten.

P.S.: Wo hast Du denn überhaupt identische Bedingungen in allen 3 Mengen?
Wieso ein Union All auf die Abfrage einer jeweils identischen Tabelle?
Bei gleicher Basistabelle: Wieso einmal ein singuläres Ausschlusskriterium (speedlimit), dass in den anderen Abfragen der gleichen Tabelle nicht auftaucht?
(Kann sein, dass das alles Sinn macht, erschließt sich mir spontan nicht so wirklich)

akretschmer
Erfahrener Benutzer
Beiträge: 7426
Registriert: So 29. Okt 2006, 13:35
Wohnort: Kaufbach, Sachsen, Germany, Germany
Kontaktdaten:

Re: Performance Optimierung von UNION Statements

Beitrag von akretschmer » Fr 11. Mai 2018, 10:52

moehre hat geschrieben:
Do 10. Mai 2018, 19:03
Hallo Zusammen,

ich habe ein SQL-Statment mit mehreren UNION-Befehlen.
Diese UNION Befehle besitzen mehrere JOINs. Kann ich die JOINS, die in allen vorkommen, auch am Ende einmalig aufrufen???
Dann würde ich ja deutlich Performancesteigerungen haben. Und momentan dauert es leider ewig...
Ich fürchte nein, da die 3 Selects unterschiedliche JOIN's haben UND und in den JOIN's unterschiedliche JOIN-Conditins haben und, basierend darauf, unterschiedliche Konstanten im Result haben.

Wenn das derzeit ewig dauert solltest Du erst einmal schauen, warum. Explain Analyse ist ein Begriff?
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Antworten