Abfrage beschleunigen

luchs3

Erfahrenes Mitglied
Hi, ich habe diese, leider ziemlich langsame, SQL Abfrage.
Ich wüsste gerne, ob ich die irgendwie beschleunigen kann.
Die Tabellen idatlifk und idatlifp sind ziemlich groß (ca. 50k Zeilen)
Ich brauche nur wenig Information aus sehr viel gefiltert.

Derzeit braucht die Abfrage ca 2 Sekunden.

Code:
SELECT ITX_BEZ, ITX_NUM FROM idattext 
INNER JOIN idatarti ON IAR_OBERGRP = ITX_NUM 
INNER JOIN idatlifp ON IAR_ARTNR = ILP_ARTNR 
INNER JOIN idatlifk 
ON ILK_BNUM = ILP_BNUM
WHERE (ILK_KUNR IN ($kunde) 
AND ILP_VTNR IN ($vtnr) 
AND ITX_KZ = 14 
AND (ITX_NUM < 96 OR ITX_NUM = 800))
GROUP BY ITX_BEZ, ITX_NUM
 
Ja, kann man. Man ersetzt die Tabellen durch Subselects in denen bereits der Fitler angewendet wird.
Eigentlich wollt ich das kurz machen anhand deines SQLs. Da du jedoch bei den Feldern nicth angegeben hast, welches Feld von welcher Tabelle stammt kann ich dies nicht.
Gehört IAR_OBERGRP zu idaarti oder zu idattext? WIe siehts mit

Nun, ich geh mal davon aus, das ich die Preffixe entschlüsseln konnte
ITX_ = idattext
ILP_ = idatlifp
ILK_ = idatlifk
IAR_ = idatarti

Ich habe jetzt mal aufgrund von Vermutungen der Zusammenhänge und der jeweiligen Grösse der Tabellen sowie der geratenen Resultatmengen der gefilterten Tabellen das folgende Beispiel zusammengestiefelt.

SQL:
SELECT DISTINCT
	ITX_BEZ, 
	ITX_NUM 
FROM
	idatarti
	INNER JOIN (	SELECT
						ILP_ARTNR,
						ILP_BNUM
					FROM
						idatlifp
					WHERE
						ILP_VTNR IN ({$vtnr})
						AND ILP_BNUM IN (	SELECT
												ILK_BNUM
											FROM
												idatlifk
											WHERE
												ILK_KUNR IN ({$kunde})
										)
				) AS ilp
		ON IAR_ARTNR = ILP_ARTNR
	INNER JOIN (	SELECT
						ITX_BEZ,
						ITX_NUM
					FROM
						idattext
					WHERE
						ITX_KZ = 14
						AND ITX_NUM < 96 OR ITX_NUM = 800
				) AS itx
		ON IAR_OBERGRP = ITX_NUM;

Ich habe mehrere Dinge eingebaut.

item: Die Tabellen Vorfiltern mittels Subqueries
item: Da wo ich erwartet haben, das sich die Anzahl der gewählten Datensätze einerTabelle aufgrund eines Resultates einer anderen Tabelle stark reduziert diese mal in den WHERE-Teil verschoben.
item: den GROUP BY durch DISTINCT ersetzt, da du einfache keine doppelten Datensätze haben willst, ansonsten aber keine GROUP-Funktionen verwendest

Es igbt einige einfache Regeln zur Performance-Verbesserung:
item: So früh wie möglich die Daten reduzieren, bevor man sie mit anderen Daten kombiniert
item: möglichst wenig Funktionen einbauen
item: Gute Indexe setzen. Bei wenig verwedneten Feldern den Index ggf so setzen, damit die DB nicht auf die Tabelle zugreiffen muss, sondern alles im Index vorfindet
item: Pröbeln. Verschiedene Varianten ausprobieren. Es gibt keine eindeutige Lösung

Nachtrag:
Ach herrlich, ich liebe Performance-Verbesserungen. Stundenlanges Pröbeln und am Schluss dem Chef 70% Geschwindigkeitssteigerung presentieren...
 
Zuletzt bearbeitet von einem Moderator:
Aber hallo, das ist ca. 60% schneller.
Da werd ich mich mal etwas mehr damit beschäftigen.
Nicht schlecht!

Vielen Dank
 

Neue Beiträge

Zurück