View Full Version : Schlechte SQL Performance bei Join?
(right oder left join ist hier verkehrt!!! das ist ein klassischer Fall für einen inner join).
Hallo,
ich habe das ganze nun auch mal auf einer 170er (220CPW) mit V5R2 getestet.
Beide Tabellen habe ich nun per SQL (CREATE TABLE) erstellt.
Erstellte Indexe:
MATINDEXI2: IXFNAM, IXTEXT, IXRECL
DBTEXTI1: PDBTDT (Empfohlen vom SQL Optimizer)
Nun frage ich einen Suchbegriff ab, der insgesamt nur aus 85 Zeilen besteht. Dies dauert beim INNER JOIN 46 Sekunden (eine Seite weiter blättern dauert 19 Sek!) und beim RIGHT JOIN nur 0,1 Sek (Blättern auch nur 0,0 Sek!).
Bei Abfrage eines Suchbegriffs, der insgesamt aus 38450 Zeilen besteht, ist das Ergebnis anders:
INNER JOIN: 0,2 Sek
RIGHT JOIN: 7,2 Sek (wobei das Blättern hier ebenfalls etwas flotter ist als beim INNER Join)
Muss ich also in meiner Indexierungsdatei erstmal abfragen wieviel Zeilen von der Abfrage betroffen sind und dann jeweils den RIGHT JOIN oder den INNEr JOIN verwenden? ;-)
Gruß
Matthias
... das Problem ist die join order
- die Auswahlfelder sind in der Tabelle a
- die Sortierfelder sind in der Tabelle b
--bei großer Trefferzahl wäre es günstiger die Sortierung vorzuziehen
--bei kleiner Trefferzahl wäre es günstiger die Auswahl vorzuziehen
durch die Auswahl des Joins wird die Entscheidung des Optimizers nach a oder b beeinflusst!
Wenns um Anzeige geht, kann man das auch durch Optimize for 20 rows beeinflussen (BTW: das ist einer der Gründe, warum der Ooops Nerv und explain schrott ist!)
Hast du beide Konstellationen und beides soll schnell sein, erreichst du das auch durch Redundanz, sprich: Aufnahme der Sortierfelder in die MATINDEX (was bei schwacher Rechenleistung sicher das Beste ist)
D*B
Hallo,
ich habe das ganze nun auch mal auf einer 170er (220CPW) mit V5R2 getestet.
Beide Tabellen habe ich nun per SQL (CREATE TABLE) erstellt.
Erstellte Indexe:
MATINDEXI2: IXFNAM, IXTEXT, IXRECL
DBTEXTI1: PDBTDT (Empfohlen vom SQL Optimizer)
Nun frage ich einen Suchbegriff ab, der insgesamt nur aus 85 Zeilen besteht. Dies dauert beim INNER JOIN 46 Sekunden (eine Seite weiter blättern dauert 19 Sek!) und beim RIGHT JOIN nur 0,1 Sek (Blättern auch nur 0,0 Sek!).
Bei Abfrage eines Suchbegriffs, der insgesamt aus 38450 Zeilen besteht, ist das Ergebnis anders:
INNER JOIN: 0,2 Sek
RIGHT JOIN: 7,2 Sek (wobei das Blättern hier ebenfalls etwas flotter ist als beim INNER Join)
Muss ich also in meiner Indexierungsdatei erstmal abfragen wieviel Zeilen von der Abfrage betroffen sind und dann jeweils den RIGHT JOIN oder den INNEr JOIN verwenden? ;-)
Gruß
Matthias
M.E. ist das ganze auch eine Sache der Query Engine!
Mit Release V5R2 wird alles (was einen join hat) noch mit der CQE ausgeführt. CQE optimiert nur basierend auf Schätzwerten und prüft nicht die tatsächlichen Daten (Statistiken wurden erst mit Release V5R2 eingeführt und werden nur von der SQE geprüft!). In Deinem Fall wird also festgelegt, dass in der vorgegebenen Konstellation ein bestimmter Zugriff der optimale ist. Der Index-Advice nur auf das Datum ist m.E. nicht korrekt bzw. komplett (ist aber noch CQE bei der noch der ORDER BY sehr stark in die Berechnung einbezogen wird). Die lfd Nr. sollte auf alle Fälle mit dabei sein.
Das Verhalten auf dieser Maschine und das Verhalten auf einer Maschine mit einem höheren Release und der Verwendung der SQE kann m.E. nicht über einen Kamm gescheert werden.
Übrigens ... der Visual explain berücksichtigt auch das Optimierungsziel (OPTIMIZE FOR X ROWS). ... und macht eigentlich nur den verwendeten Zugriffsplan sichtbar!
Alle dynamischen SQL Interfaces (z.B.STRSQL, iSeries Navigator, embedded dynamisches SQL, JDBC ...) werden per Default so optimiert, dass der erste Block der Daten möglichst schnell zurückkommt, während statisches SQL per Default so optimiert wird, dass alle Daten möglichst schnell zurückkommen.
Mit Optimize for X rows kann man z.B. bei statischem SQL, z.B. bei seitenweisen Subfile-Anzeige das Optimierungsziel verändern. Ist x eine sehr kleine Zahl ist das Optimierungsziel *FIRSTIO ist x eine sehr große Zahl oder ALL wird das Optimierungsziel *ALLIO verwendet. Das Optimierungsziel kommt eigentlich nur dann zum Zug, wenn es um die Entscheidung geht Table Scan oder doch lieber Index Zugriff.
Birgitta