# Sql Anfrage nach einer Zeile beenden



## jhjh (24. Nov 2019)

Hallo,

es gibst ja in SQL zB *Fetch* *First Only n Rows* bzw *limit n* um sich nur eine bestimmte Anzahl von Zeilen anzeigen zu lassen. Das Problem ist hier, dass die Verarbeitung nach n Zeilen trotzdem weiterläuft und am ende quasi nur aus einem Stapel die ersten n Zeilen ausgegeben werden. Ich möchte aber, dass die Ausführen nach n Zeilen beendet wird. Wie mache ich das am besten ? Ich verwende DB2.


----------



## mihe7 (24. Nov 2019)

Wie kommst Du darauf, dass da eine Verarbeitung weiterläuft?


----------



## jhjh (24. Nov 2019)

Ist dem nicht so ? 
Also ich habe mehrere Tabellen mit sehr vielen Daten in einer Abfrage mit Joins verknüpft werden. Wenn ich auch nur eine Zeile ausgeben möchte dauert es halt ewig (wie lange genau weiß ich gerade nicht, aber ist schon seit 7 min am laufen), deswegen war meine Vermutung, dass nach einer Zeile es trotzdem weiterläuft....


----------



## mihe7 (25. Nov 2019)

Das hört sich für mich eher nach fehlenden Indizes an. 

Was die Verarbeitung der Zeilen betrifft: das kommt auf die Abfrage an. Ein ORDER BY muss nun mal erst sortieren, bevor die 1. Zeile zurückgegeben werden kann. Man kann das Ergebnis vorher ggf. einschränken.


----------



## jhjh (25. Nov 2019)

Ja ich frickel mich da mal durch, danke!


----------



## kneitzel (25. Nov 2019)

Neben fehlenden Indizes kann es natürlich auch an der Abfrage liegen. Typische Gründe können halt schlechte Filterausdrücke sein (z.B. jedes Feld muss aktiv angepackt werden ohne dass ein vorhandener Index verwendet werden kann) oder Verknüpfungen wo aus n und m Zeilen dann intern n*m Zeilen aufgebaut werden müssen...
Und natürlich können ggf auch existierende Locks durch andere Abfragen Ursache sein - also Probleme an anderer Stelle können dies natürlich auch verursachen.

Eine Abfrage über 7 Minuten ist aber generell etwas dubios und da sollte analysiert werden:
- DB2 hat ein EXPLAIN Befehl um sich den Execution Plan anzeigen zu lassen.
- Generell bietet DB2 die Möglichkeit, fehlende Indizes zu finden: https://www.ibm.com/support/knowled...riginal/oslc/web/rs_t_find_missing_index.html
Aber Achtung: Indizes erhöhen die Abfrage-Geschwindigkeit aber sie verlangsamen z.B. Inserts und Updates! Also immer die ganze Performance im Blick haben!
- Natürlich ganz wichtig: CREATE EVENT MONITOR Befehl von DB2: https://www.ibm.com/support/knowled...com.ibm.db2.luw.sql.ref.doc/doc/r0055061.html


----------



## LimDul (25. Nov 2019)

Bei einer ordentlichen Datenbank (und sowenig ich DB2 mag - es ist eine ordentliche Datenbank) kann man davon ausgehen, dass die nicht mehr tut als notwendig. Das heißt, wenn du nur die erste Zeile haben willst, ermittelt die Datenbank nicht mehr als notwendig um diese erste Zeile zu ermitteln. Sprich, ihr sagen, dass sie danach aufhören soll, brauchst du nicht - macht sie sowieso. (der Cursor wird zwar noch offen sein, bis das Query wirklich geschlossen wird, aber das sind Details).

Das Problem ist nur, wie oben schon erwähnt:
* Order by - dann müssen ggf. alle Zeilen gelesen werden, um die erste zu ermitteln
* Fehlende Indexe - um zu ermitteln, was die korrekten Zeilen bei einem Join sind muss dann ein Full Table Scan gemacht werden, also die gesamte Tabelle einmal gelesen werden
* Ungünstige Where Bedingungen - um zu ermitteln, was die korrekten Zeilen sind muss dann ein Full Table Scan gemacht werden, also die gesamte Tabelle einmal gelesen werden

Wenn man nun mehrere Joins hat potenziert sich das ganze.

Ein Query was 7+ Minuten läuft und nicht gerade eine hochkomplexe Data Warehouse Query ist, dauert zu lang. Dann ist entweder das Query falsch oder es stimmt was am Datenbankschema (Indexe & Co) nicht oder die Maschine ist im Verhältnis zur Datenmenge massive zu klein (Also mehrere Millionen Datensätze und 5212 MB RAM oder so).


----------

