AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Abfrage mit Summe optimieren
Thema durchsuchen
Ansicht
Themen-Optionen

Abfrage mit Summe optimieren

Ein Thema von EarlyBird · begonnen am 27. Aug 2014 · letzter Beitrag vom 28. Aug 2014
Antwort Antwort
Seite 2 von 3     12 3      
Dejan Vu
(Gast)

n/a Beiträge
 
#11

AW: Abfrage mit Summe optimieren

  Alt 27. Aug 2014, 15:21
Zeig doch mal deinen Ansatz. Ich glaube, es ist nicht klar, wo der Vorteil von ROW_NUMBER ggü dem Feld 'lfd' ist.

Edit: Ich sehe gerade
SQL-Code:
SELECT *,
  SUM(wert) OVER(ORDER BY lfd
     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          AS Summe
  FROM Table1
ungetestet (soll ANSI-SQL sein)

Und woher hab ich das?
http://stackoverflow.com/questions/8...l-in-sqlserver

Geändert von Dejan Vu (27. Aug 2014 um 15:31 Uhr)
  Mit Zitat antworten Zitat
EarlyBird

Registriert seit: 29. Mär 2007
235 Beiträge
 
#12

AW: Abfrage mit Summe optimieren

  Alt 27. Aug 2014, 15:32
Danke Dejan Vu
Das sind Ansätze die weiterhelfen.
Werde es gleich Testen
  Mit Zitat antworten Zitat
EarlyBird

Registriert seit: 29. Mär 2007
235 Beiträge
 
#13

AW: Abfrage mit Summe optimieren

  Alt 27. Aug 2014, 15:59
SQL-Code:
SELECT *,
  SUM(wert) OVER(ORDER BY lfd
     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          AS Summe
  FROM Table1
Das funktioniert in SQL 2005 leider noch nicht
Habe es gerade auf einem Sql 2012 Server getestet da klappt es.

Das optimiert unter SQLServer 2012 noch mal von 316ms auf 79ms
(Temporäre Tabelle gegenüber select sum over)

Leider kann ich es unter Sql 2005 noch nicht nutzen
Vielen Dank
(auch an jobo)
  Mit Zitat antworten Zitat
EarlyBird

Registriert seit: 29. Mär 2007
235 Beiträge
 
#14

AW: Abfrage mit Summe optimieren

  Alt 27. Aug 2014, 17:04
ein keines Problem gibt es noch:
SQL-Code:
SELECT *,
  SUM(wert) OVER(ORDER BY lfd
     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          AS Summe
  FROM Table1 where lfd > 111
füge ich ein where in die Sqlabfrage ein dann summiert die over funktion erst ab dem ersten wert der Abfrage und nicht nach dem ersten wert in der Tabelle
ich habe es jetzt so gelöst:
SQL-Code:
select * from ( select lfd, wert,
SUM(wert) OVER(ORDER BY lfd
     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          AS Summe
  FROM Table1) as tabl1 where tabl1.lfd > 111
Aber das bremst das ganze wieder aus
Ich habe die Over Funktion mit verschiedenen Parametern getestet leider ohne Erfolg.
Gibt es eine Möglichkeit mit der Over Funktion die Summe ab dem Ersten Datensatz aus der Tabelle zu bilden?

Geändert von EarlyBird (27. Aug 2014 um 17:11 Uhr)
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#15

AW: Abfrage mit Summe optimieren

  Alt 27. Aug 2014, 17:32
Was brauchst Du denn jetzt, 2005 oder 2012?

Falls ich oben gemeint war, ich habe nie geschrieben, dass row_number die Lösung ist.
Es war lediglich eine Erläuterung, um die entsprechenden Funktionen (Window Funktions) zu finden und einzuordnen. Dass ich selber Zweifel hatte, ob die Window Function Implementierung in Version 2005 bereits ausreicht, das zu lösen, hab ich ja angedeutet.

In dem Link von Dejan Vu ist ein Beispiel für 2005, allerdings mit Cross Apply, wie das performed, kann ich nicht sagen, es sollte jedenfalls funktionieren:
Code:
select
     t.lfd,
     t.wert ,
    rt.runningTotal
  from Table1 t
 cross apply (select sum(wert) as runningTotal
             from Table1
             where lfd <= t.lfd
          ) as rt
order by t.lfd
Mit einer reinen SQL Lösung sparst Du jedenfalls das Handling der Temp Table und brauchst keine SP.
Wenn es schnell genug ist, würde ich das vorziehen.

Das Problem mit der Where Bedingung habe ich nicht verstanden...
Zitat:
erst ab dem ersten wert der Abfrage und nicht nach dem ersten wert in der Tabelle
??
Gruß, Jo
  Mit Zitat antworten Zitat
EarlyBird

Registriert seit: 29. Mär 2007
235 Beiträge
 
#16

AW: Abfrage mit Summe optimieren

  Alt 27. Aug 2014, 22:13
ich brauch die Lösung für den SQL Server 2005
Ich habe aber einen 2012 auf dem ich auch Testen kann.
Und ich hoffe das der 2005er bald ausgetauscht wird.

Dein Tipp mit OVER war ja richtig ich habe es nur nicht sofort erkannt.

Die 2005er Lösung mit cross apply habe ich getestet.
Das ist genauso langsam wie mein ursprüngliche Abfrage.

Ich werde es dann wohl mit der Temp Tabelle machen.

Zu meinem Problem mit der Where Bedingung.
Wenn ich folgende Abfrage ausführe:
SQL-Code:
SELECT *,
  SUM(wert) OVER(ORDER BY lfd
     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          AS Summe
  FROM Table1 where lfd > 3
Dann erhalte ich in der Spalte Summe nur die Werte summiert die in der Abfrage enthalten sind.
Die ersten 3 Werte werden nicht mit summiert.
Ich benötige aber immer die Summe aller Werte aus der Tabelle
Ich hoffe so ist es etwas verständlicher
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#17

AW: Abfrage mit Summe optimieren

  Alt 28. Aug 2014, 07:51
Gut, im Prinzip würde ich das mit einem verschachtelten Select machen, so wie Du es bereits probiert hast. Wenn das zu einem Performanceeinbruch führt, deutet das auf ein Optimizerproblem hin. Vlt kann man da mit hints arbeiten, die das System zwingen, schön brav erst innen, dann außen durchzuführen.
Kann aber auch sein, dass bei einer sehr großen Datenmenge, das innere Ergebnis so groß ist, dass er Kopfschmerzen kriegt bei der äußeren Eingrenzung (index auf lfd nicht mehr wirksam)
Vielleicht kann mit UNBOUNDED PRECEDING noch spielen, denn es geht ja eigentlich um diese Einschränkung. Ich arbeite in der Praxis nicht mit MSSQL, vielleicht gibt's noch Möglichkeiten.
Oder je nach Anwendungsfall den Zugriff auf indexed views umstellen. Bietet sich aber wohl nur an, wenn die Grundmenge nur nach oben hin wächst und nicht ständig vollständig neu aufgebaut werden muss.
Ist doch aber alles egal, wenn Du eh 2005 nimmst, oder?
Gruß, Jo
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#18

AW: Abfrage mit Summe optimieren

  Alt 28. Aug 2014, 08:21
Der Aufwand bei einem 'naiven' Subselect wird O(n^2) bleiben, denn für jede Zeile wird die Summe ausgerechnet. Bei einem einmaligen 'manuellen' Rechnen dagegen ist der Aufwand O(n). Ich kann mir jetzt nicht vorstellen, das ein Optimizer begreift, das man in einem Subselect ein 'running total' ausrechnet und das auch in O(1) ginge (Ergebnis der letzten Zeile + Wert). Aber Optimizer vollbringen wirklich wahre Wunder, vielleicht auch hier.
Tipp zur gefilterten Anzeige :
SQL-Code:
select * from (
  SELECT *,
         SUM(wert) OVER(ORDER BY lfd
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          AS Summe
  FROM Table1
) x where lfd>3
Diese Query erzeugt zuerst die laufende Summe über alle Zeilen und zeigt dann nur die Zeilen mit 'lfd' > 3 an. Schnell genug sollte das auch sein.

Die laufende Summe (bzw. die Pflege) könnte man auch über einen Trigger lösen, aber derart redundante Information hat normalerweise nichts in einer Produktivdatenbank (3NF) verloren.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#19

AW: Abfrage mit Summe optimieren

  Alt 28. Aug 2014, 08:29
Tipp zur gefilterten Anzeige :
SQL-Code:
select * from (
  SELECT *,
         SUM(wert) OVER(ORDER BY lfd
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          AS Summe
  FROM Table1
) x where lfd>3
Ich glaub das hatte er schon, ist zu langsam.
Daher meine Vermutung, große Datenmenge (hier dann als zwischenergebnis), das harmlose id>3 macht einen Fullscan auf dem Zwischenergebnis (das auf Platte liegt) usw usw. Aber eben vielleicht auch nur ein doofer Optimizer Pfad.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#20

AW: Abfrage mit Summe optimieren

  Alt 28. Aug 2014, 08:44
Wofür wird das gebraucht, bzw. wie sieht die weitere Verarbeitung aus?

Es kann durchaus Sinn machen, diese Informationen erst in der nachgelagerten Verarbeitung zu ermitteln.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 14:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz