[NEWSboard IBMi Forum]

Hybrid View

  1. #1
    Registriert seit
    Mar 2002
    Beiträge
    5.368
    ... ich meine schon, was ich schreibe!
    zur Problemstellung:
    ich gehe mal davon aus, dass DBTEXT nicht klein ist und MATINDEX um etliches größer und dass die Ergebnismenge eine hohe Selektivität hat, also um ein Vielfaches kleiner als DBTEXT ist. (right oder left join ist hier verkehrt!!! das ist ein klassischer Fall für einen inner join).

    Wenn obige Konstellation stimmt, hast du zwei Möglichkeiten:
    1. den Index auf das Sortierfeld zu löschen (falls der anderweitig nicht benötigt wird)
    2. Zweistufig arbeiten und im ersten Schritt ein Substrat ziehen (create table qtemp.ddd as (select ... from... !!! ohne order by!!!) und im zweiten Schritt select * from qtemp.ddd order by...)
    Das auch denkbare Festschreiben der Join Reihenfolge per QAQQINI könnte auch klappen, würde ich aber lassen, das macht andere Queries kaputt.

    Dass da eine Datenbank schneller als die andere sein kann, unabhängig von den Lizenzkosten, liegt daran, dass auf unterschiedliche Ziele optimiert wird - jede Datenbank hat ihre Stärken und Schwächen, die in einem inneren Zusammenhang stehen und da liegt es bei MySQL (bei der Abwesenheit von Lizenzkosten) schon nahe für eine spezifische Aufgabe, wenn sie denn kritisch ist, sich das Beste aus mehreren Welten zusammen zu packen!

    D*B


    Zitat Zitat von holgerscherer Beitrag anzeigen
    Moment - Dieters Sätze sind manchmal mit einer gewissen Vorsicht zu geniessen, ein wenig Ironie und Bissigkeit kann schon dabei sein. Da ich gerade neben ihm sitze, gehe ich davon aus, dass das nicht seine ultimative Meinung zur Lösung des Problems ist. Aber wie geschrieben, nun brauchts Detailinfos.

    Nachtrag: ich werde so aus dem zweiten Blick nicht schlau, was Du genau aus welchen Dateien holst. Könntest Du die beiden Dateien genau beschreiben, was wo liegt, und *wann* Du welche Sätze mit welcher Kondition Verknüpfung holen willst. Und - bei solchen Dingen - ist Releasestand und PTF-Stand wichtig.


    -h
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  2. #2
    cbe is offline [professional_User]
    Registriert seit
    May 2005
    Beiträge
    392
    Hallo allerseits!
    Zitat Zitat von BenderD Beitrag anzeigen
    ... 2. Zweistufig arbeiten und im ersten Schritt ein Substrat ziehen (create table qtemp.ddd as (select ... from... !!! ohne order by!!!) und im zweiten Schritt select * from qtemp.ddd order by...)
    hier stimme ich Dieter voll zu, das zweistufige Arbeiten hat mir auch schon deutlich Laufzeit gespart.
    Ich mag allerdings dabei keine Objekte explizit erstellen, WITH ist mir sympatischer, und das geht auch mehrstufig:

    Code:
    with x as (
    select IXFNAM, IXTEXT, IXRECL from matindex
    where
          IXFNAM = 'DBTEXT'
      and IXTEXT =    'KUNDE'),
    y as (SELECT
           'DBTEXT', PDPRN2, PDPRN3, PDKDK, PDMA, PDBTDT,
     rtrim(PDTXT1)||rtrim(PDTXT2)||rtrim(PDTXT3)||
     rtrim(PDTXT4)||rtrim(PDTXT5) as Txt
    FROM DBTEXT right join x on IXRECL  = PDLFDN)
    select  'DBTEXT', PDPRN2, PDPRN3, PDKDK, PDMA, PDBTDT, Txt
    FROM y   order by pdbtdt
    (Ich hoffe, die Syntax stimmt so...)

    Hiermit erzwingt man, dass das Sortieren erst am Schluss gemacht wird, was manchmal sparsamer ist.
    Würde mich interessieren, ob es hier auch hilft.

    Ob der Right-Join hier Sinn macht usw. will ich gar nicht weiter ansprechen, das wurde ja schon diskutiert.

    Gruß, Christian

  3. #3
    Registriert seit
    Mar 2002
    Beiträge
    5.368
    ... frei nach Theorie zieht der Optimizer das gesamte SQL Statement zur Optimierung heran, arbeitet also nach dem Prinzip: entscheidend ist, was hinten rauskommt. Hier hält sich ein weiterer Mythos hartnäckig, das die Performance einer Abfrage von der geschickten Formulierung abhänge. Wenn sich der Optimizer von der Art der Formulierung der gleichen Abfrage (:= gleiches Ergebnis!) beeindrucken lässt, dann ist das ein Bug im Sinne von SQL (da zähle ich auch die Existenz zweier Query Engines dazu, die unter sich auswürfeln wer dran ist), oder ein Seiteneffekt des Nebenkriteriums des Optimizers: der nimmt das aktuell best bewerteteste Ergebnis, wenn ihm das gut genug ist, oder lange genug gesucht wurde.

    Mehrstufigkeit wird also durch with Formulierungen nur zufällig erreicht, eine temporäre Tabelle erzwingt das. Ich bin kein Freund davon, aber damit kann man Teile mit hoher Selektivität (kleine Trefferzahl) vorziehen, um damit Abfragen zu beschleunigen.

    Für die Ausgangslage, da könnte noch das parallel Database Feature weiterhelfen (nicht billig!), das verschiebt die Optimierung in die Richtung, die hier gebraucht wird.

    D*B


    Zitat Zitat von cbe Beitrag anzeigen
    Hallo allerseits!

    hier stimme ich Dieter voll zu, das zweistufige Arbeiten hat mir auch schon deutlich Laufzeit gespart.
    Ich mag allerdings dabei keine Objekte explizit erstellen, WITH ist mir sympatischer, und das geht auch mehrstufig:

    Code:
    with x as (
    select IXFNAM, IXTEXT, IXRECL from matindex
    where
          IXFNAM = 'DBTEXT'
      and IXTEXT =    'KUNDE'),
    y as (SELECT
           'DBTEXT', PDPRN2, PDPRN3, PDKDK, PDMA, PDBTDT,
     rtrim(PDTXT1)||rtrim(PDTXT2)||rtrim(PDTXT3)||
     rtrim(PDTXT4)||rtrim(PDTXT5) as Txt
    FROM DBTEXT right join x on IXRECL  = PDLFDN)
    select  'DBTEXT', PDPRN2, PDPRN3, PDKDK, PDMA, PDBTDT, Txt
    FROM y   order by pdbtdt
    (Ich hoffe, die Syntax stimmt so...)

    Hiermit erzwingt man, dass das Sortieren erst am Schluss gemacht wird, was manchmal sparsamer ist.
    Würde mich interessieren, ob es hier auch hilft.

    Ob der Right-Join hier Sinn macht usw. will ich gar nicht weiter ansprechen, das wurde ja schon diskutiert.

    Gruß, Christian
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  4. #4
    Registriert seit
    Nov 2003
    Beiträge
    2.403
    Leg mal eine logische Datei für DBTEXT mit einem Zugriffspfad über die Spalten PDLFDN und PDBTDT an und probier dann mal mit ORDER BY PDLFDN, PDBTDT.

  5. #5
    Registriert seit
    Jun 2006
    Beiträge
    356
    Zitat Zitat von Pikachu Beitrag anzeigen
    Leg mal eine logische Datei für DBTEXT mit einem Zugriffspfad über die Spalten PDLFDN und PDBTDT an und probier dann mal mit ORDER BY PDLFDN, PDBTDT.
    Hallo Pikachu,

    das geht dann flott. Aber es ist ja dann nicht mehr nach dem Datum (PDBTDT) sortiert.

    @Holger: In der Datei DBTEXT sind 800.000 Sätze enthalten. Es enthält 5 Textspalten (PDTXT1 - 5 jeweils 50 Stellen lang), eine eindeutige laufende Nummer (PDLFDN), ein Datumsfeld (PDBTDT). Nun möchte ich die Textspalten per Freitextselektion durchsuchen. Damit ich nicht jeden Datensatz mit SQL UCASE(TEXT) Like '%SUCHBEGRIFF%' prüfen muss, lasse ich jeden Abend eine Wort Indexierung erstellen (Tabelle MATINDEX). Jedes Wort wird dabei in Großschrift in die Datei MATINDEX geschrieben mit einem Bezug auf die laufende Nummer (PDLFDN) der Datei DBTEXT.

    Bisher hatte ich für die Abfrage ein Cobol Programm erstellt, was für den Suchbegriff jeweils die Sätze aus der MATINDEX liest und die dazugehörigen DBTEXT Datensätze in ein Sortfile einliest, damit nach PDBTDT sortiert werden kann.

    Dieses Cobolprogramm wollte ich nun durch ein SQL Cobolprogramm ersetzen.


    Gruß
    Matthias

  6. #6
    Registriert seit
    Jun 2006
    Beiträge
    356
    Zitat Zitat von BenderD Beitrag anzeigen
    (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

  7. #7
    Registriert seit
    Mar 2002
    Beiträge
    5.368
    ... 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


    Zitat Zitat von schatte Beitrag anzeigen
    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
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  8. #8
    Registriert seit
    Aug 2001
    Beiträge
    2.931
    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
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 5. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

Similar Threads

  1. SQL inner join
    By Robi in forum NEWSboard Programmierung
    Antworten: 7
    Letzter Beitrag: 22-06-07, 15:52
  2. SQL left join
    By ahingerl in forum IBM i Hauptforum
    Antworten: 8
    Letzter Beitrag: 08-12-06, 08:28
  3. SQL JOIN
    By steven_r in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 19-10-06, 07:56
  4. MS Access ODBC mit JOIN: SQL FEHLER666
    By olafu in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 05-10-06, 08:13
  5. SQL Performance
    By mariupol1963 in forum IBM i Hauptforum
    Antworten: 9
    Letzter Beitrag: 11-08-06, 13:06

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •