AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Ausführunsplan / SQL Optimizer
Thema durchsuchen
Ansicht
Themen-Optionen

Ausführunsplan / SQL Optimizer

Ein Thema von exilant · begonnen am 6. Aug 2014 · letzter Beitrag vom 8. Aug 2014
Antwort Antwort
exilant

Registriert seit: 28. Jul 2006
134 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Ausführunsplan / SQL Optimizer

  Alt 6. Aug 2014, 14:41
@gmc616: Danke für deine Antwort. Natürlich ist das Feld vom Typ integer. Leider nicht als FK definiert obwohl es an dieser Stelle Sinn machen würde. Aber das sollte keinen Einfluss auf den Optimizer haben.
Deine Abfrage führt zum gleichen Plan. Es ist also egal ob mit JOIN oder WHERE die Tabellen verbinde. Es bleibt bei NATURAL.
Ich bin echt ratlos.
Anything, carried to the extreme, becomes insanity. (Exilant)
  Mit Zitat antworten Zitat
gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Ausführunsplan / SQL Optimizer

  Alt 6. Aug 2014, 15:40
Sorry, ich bin in FB nicht fit, nutze ihn garnicht.

Die Überlegung war, dass evtl. die beiden IDs unterschiedliche Integer (smallint, longint etc.) sein könnten und deswegen FB einen eigenen Index zusammen baut.
Die Erfahrung zeigt auch, das manchmal ein einfaches umbauen des Statements die SQL-Engine dazu veranlasst, anders zu arbeiten ( z.B. die andere Tabelle indiziert ).

z.B. einfach mal umdrehen
Code:
v2fertigartikel.id=v2ps.v2fertigartikel
oder das FROM umstellen ...

oder evtl. einen FK zusätzlich über v2fertigartikel.id

ist aber alles nur geraten, wie erwähnt, kenne/nutze ich FB nicht.
  Mit Zitat antworten Zitat
exilant

Registriert seit: 28. Jul 2006
134 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Ausführunsplan / SQL Optimizer

  Alt 6. Aug 2014, 16:09
Die Felder sind beide als INTEGER NOT NULL deklariert. Ein Umdrehen des Vergleiches habe ich auch schon versucht. Das bringt nichts. Ich wäre aber auch schreiend aus dem Fenster gesprungen wenn das funktioniert hätte....
Ich werde jetzt mal das mit dem FK probieren. Allerdings laufen ein paar ältere Anwendungen auf der Datenbank. Da bin ich mir nicht sicher welche Seiteneffekte ich mir mit der Deklarion des FK einhandle. Ich sehe die Exceptions durch constraints violations schon vor meinem geistigen Auge.
Schaun mer mal.
Trotzdem Danke,
Martin
Anything, carried to the extreme, becomes insanity. (Exilant)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#4

AW: Ausführunsplan / SQL Optimizer

  Alt 6. Aug 2014, 16:10
Kann es sein, dass auf v2ps.status auch ein Index ist, und er diesen im ersten Schritt (bevor er den eigentlichen Join durchführt) verwendet, um die Zeilen von v2ps anhand der where-Bedingung einzugrenzen? Dann kommen anschließend die ids unsortiert heraus, sodass er keinen Merge-Join durchführen kann (und daher von den Indizes auf den id-Spalten nicht profitiert).

Vorausgesetzt, ich habe diesen Query Plan überhaupt richtig interpretiert... habe auf die Schnelle irgendwie keine Dokumentation dazu gefunden, wie diese Ausgabe überhaupt zu lesen ist.

Ich würde auf jeden Fall mal die Where-Bedingung testweise weglassen, um zu gucken, was passiert.

Geändert von Namenloser ( 6. Aug 2014 um 16:14 Uhr)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#5

AW: Ausführunsplan / SQL Optimizer

  Alt 6. Aug 2014, 16:14
Vielleicht ist die Tabelle 'v2FertigArtikel' zu klein?
  Mit Zitat antworten Zitat
exilant

Registriert seit: 28. Jul 2006
134 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Ausführunsplan / SQL Optimizer

  Alt 6. Aug 2014, 17:16
Zu klein ist so eine Sache. Im Augenblick sind knapp 8.000 Datensätze drin.
Die Performance der Abfrage ist im Augenblick auch kein Problem. Der Firebird läuft auf einer Mödermaschine unter Ubuntu Server. Granatenschnell. Aber die Datenmenge wird bald steil nach oben gehen. Ich rechne mit mehr als 1.500 neuen Einträgen/Monat ab Ende des Jahres.
Und es geht auch um das Grundsätzliche. Ich sehe da ein Problem.
Anything, carried to the extreme, becomes insanity. (Exilant)
  Mit Zitat antworten Zitat
exilant

Registriert seit: 28. Jul 2006
134 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Ausführunsplan / SQL Optimizer

  Alt 6. Aug 2014, 17:20
@Namenloser: Ja. Auf Feld STATUS gibt es einen Index. Warum das aber dazu führen sollte dass der Index für den PK in v2fertigartikel nicht benutzt wird ist mir nicht klar.
Es ist eine simple 1-1 Beziehung.
Aber trotzdem Danke.
Anything, carried to the extreme, becomes insanity. (Exilant)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#8

AW: Ausführunsplan / SQL Optimizer

  Alt 6. Aug 2014, 17:35
Vielleicht ist hier etwas für Dich zu holen?

Gruß
K-H

P.S.
Das Umstellen der Tabellenreihenfolge im FROM kenn ich noch von den älteren MSSQL-Servern, da waren Abfragen noch handoptimiert.
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#9

AW: Ausführunsplan / SQL Optimizer

  Alt 6. Aug 2014, 19:19
@Namenloser: Ja. Auf Feld STATUS gibt es einen Index. Warum das aber dazu führen sollte dass der Index für den PK in v2fertigartikel nicht benutzt wird ist mir nicht klar.
Weil der Nutzen des Index beim Join, soweit ich weiß, hauptsächlich darin besteht, dass durch ihn beide Relationen bezüglich der Verknüpfungs-Spalte sortiert sind. Dadurch kann man einen recht effizienten Merge-Join durchführen.

Folgende Tabellen als Beispiel:
Code:

Tabelle X   Tabelle Y
 A B         A C
---------    ---------
 1 42         2 0
 2 27         3 1
 3 40         4 2
 5 38         5 3
 7 39         7 4
 9 41         9 5
Beide Tabellen haben einen Index auf Spalte A (aufsteigend sortiert), und die Abfrage ist select A, B, C from X join Y on X.A = Y.A .

Man geht nach folgendem Pseudocode vor:
Code:
CursorX := Zeiger auf erste Zeile von Tabelle X.
CursorY := Zeiger auf erste Zeile von Tabelle Y.

while (not CursorX.EOF and not CursorY.EOF) do
begin
  if CursorX.A = CursorY.A then
    Elemente von CursorX und CursorY konkatenieren und Zeile ausgeben
  else if CursorX.A > CursorY.A then
    CursorY eine Zeile weiter nach unten bewegen
  else if CursorX.A < CursorY.A then
    CursorX eine Zeile weiter nach unten bewegen
end;
(Zur Vereinfachung gehe ich hier mal davon aus, dass A in beiden Tabellen unique ist. Man kann den Algorithmus aber auch für nicht-unique Fälle verallgemeinern).

Das ist ein recht effizienter Join-Algorithmus, allerdings nur dann wirklich effizient, wenn die es für die Eingabemengen schon sortiert sind. Im obigen Beispiel ist das der Fall dank des Index.

Wenn die Abfrage jetzt aber stattdessen wäre select A, B, C from X join Y on X.A = Y.A where X.B in (42, 27, 38, 39) und auf B ein Index liegt, dann kann es sein, dass der Optimizer sich entscheidet erst mal nach der Bedingung zu filtern und dabei den Index auf B zu nutzen.

Zwischenergebnis:
Code:

Tabelle X'  Tabelle Y
 A B         A C
---------    ---------
 2 27         2 0
 5 38         3 1
 7 39         4 2
 1 42         5 3
              7 4
              9 5
Da der Index auf B benutzt wurde, sind die Zeilen von X' nun möglicherweise in einer anderen Reihenfolge und nicht mehr nach A sortiert. Folglich kann der Join nun nicht mehr so effizient mit dem Merge-Join-Algorithmus durchgeführt werden. Man könnte jetzt natürlich X' einfach noch mal extra nach A sortieren, aber möglicherweise ist es effizienter, gleich einen ganz anderen Join-Algorithmus zu verwenden, z.B. Hash-Join. Dabei nützt einem dann allerdings auch der Index auf Tabelle Y nichts mehr, weshalb er nicht benutzt wird.


Ist aber nur geraten, ich hab keine Ahnung, was der Optimizer intern macht und was für Algorithmen er verwendet.

Geändert von Namenloser ( 6. Aug 2014 um 19:23 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz