Brauche Hilfe bei der Optimierung einer MSSQL-Abfrage

VolkerMann

Grünschnabel
Hallo,

ich bin neu hier und habe ein etwas größeres Problem.

Ich habe eine Abfrage gebastetlt, die den Rechner Teilweise ganz schön in die Knie zwingt und daher einfach meine Frage an die Profis, wie ich die Abfrage effizienter machen kann.

Meine aktuelle Abfrage lautet:
Code:
SELECT	Artikel,
		Beschreibung,
		Beschreibung2,
		ArtikelKategorie,
		ProduktGruppe,
		altSumme,
		altAnzahl,
		neuSumme,
		neuAnzahl,
		CASE WHEN altSumme > 0 
		THEN	(neuSumme/altSumme)
		ELSE	0
		END AS Differenz,
		CASE WHEN altAnzahl > 0 
		THEN	(neuAnzahl/altAnzahl)
		ELSE	0
		END AS ProAnzahl,
		Einstandspreis
		
from 	(	SELECT	Artikel,
			Artikel1,
			Beschreibung,
			Beschreibung2,
			ArtikelKategorie,
			ProduktGruppe,
			altSumme,
			altAnzahl,
			sum(neuBetrag*neuMenge) AS neuSumme,
			sum(neuMenge) AS neuAnzahl,
			Einstandspreis
		
		FROM	(	SELECT	Artikel, 
					Sum(altBetrag*altMenge) AS altSumme, 
					SUM(altMenge) AS altAnzahl
		
			 FROM	(	SELECT	[Datenbank$Sales Invoice Line].[No_] AS Artikel,
						[Datenbank$Sales Invoice Line].[Unit Price] AS altBetrag,
						[Datenbank$Sales Invoice Line].[Quantity] AS altMenge
   
					FROM	[Datenbank$Sales Invoice Line]

					WHERE	([Datenbank$Sales Invoice Line].[Shipment Date] >= DATEADD(year,-1,@vonD)
						AND
						[Datenbank$Sales Invoice Line].[Shipment Date] <= DATEADD(year,-1,@bisD))
						AND
						[Datenbank$Sales Invoice Line].[No_] > '0'
						AND
						[Datenbank$Sales Invoice Line].[No_] < '99986'
						AND
						[Datenbank$Sales Invoice Line].[Item Category Code] IN (@kategorie)
				) AS Temp

			 Group BY Artikel  

			) Temp3

		INNER Join	(	SELECT	[Datenbank$Sales Invoice Line].[No_] as Artikel1,
						[Datenbank$Sales Invoice Line].[Unit Price] as neuBetrag,
						[Datenbank$Sales Invoice Line].[Description] AS Beschreibung,
						[Datenbank$Sales Invoice Line].[Description 2] AS Beschreibung2,
						[Datenbank$Sales Invoice Line].[Item Category Code] AS ArtikelKategorie,
						[Datenbank$Sales Invoice Line].[Product Group Code] AS ProduktGruppe,
						[Datenbank$Sales Invoice Line].[Quantity] AS neuMenge
						
					FROM	[Datenbank$Sales Invoice Line]
				
					WHERE	([Datenbank$Sales Invoice Line].[Shipment Date] >= @vonD
						AND
						[Datenbank$Sales Invoice Line].[Shipment Date] <= @bisD)
						AND
						[Datenbank$Sales Invoice Line].[No_] > '0'
						AND
						[Datenbank$Sales Invoice Line].[No_] < '99986'
						AND
						[Datenbank$Sales Invoice Line].[Item Category Code] IN (@kategorie)
  				) AS Temp2
		ON Artikel = Artikel1
			

	
		INNER JOIN	(	SELECT	[Datenbank$Value Entry].[Item No_] AS Artikelnr,
						CASE WHEN SUM([Datenbank$Value Entry].[Item Ledger Entry Quantity]) = 0
						THEN 0
						ELSE CONVERT(Decimal(10,5),(ROUND(((SUM([Datenbank$Value Entry].[Cost Amount (Expected)])+SUM([Datenbank$Value Entry].[Cost Amount (Actual)]))/SUM([Datenbank$Value Entry].[Item Ledger Entry Quantity])),5)))
						END AS Einstandspreis
		
					From	[Datenbank$Value Entry]

					Group by	[Datenbank$Value Entry].[Item No_]	

				

				) AS EKPreise
		ON Artikel = Artikelnr

	
		Group by 	Artikel,
				Artikel1,
				Beschreibung,
				Beschreibung2,
				ArtikelKategorie,
				ProduktGruppe,
				altSumme,
				altAnzahl,	
				Einstandspreis	
	) AS Temp4

Mit den ganzen Unterabfragen ist die Lösung sicherlich nicht gerade so gut, doch im Moment steht ich auf den Schlauch und sehe nicht, wie ich es ändern kann. Vielleicht kann mir da jemand auf die Sprünge helfen!?

Vielen Dank im Voraus!
 
Der Übersicht halber, würde ich mit Views arbeiten. Jedes Select entspricht also einer View. Dann sparst du dir schon mal die ganzen Unterabfragen.

Wenn du dieses Dataset öfter brauchst, schlage ich vor, dass du eine feste Tabelle erstellst, die die Ergebnisse zyklisch aktualisiert. Mit anderen Worten eine Ergebnis-Tabelle. Das könnte dann nachts passieren.

Der Ausführungsplan sollte dir ebenfalls Auskunft geben, an welchen Stellen besonders geackert wird.
 
Zurück