Autor Beitrag
Oppi35
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 95
Erhaltene Danke: 3



BeitragVerfasst: Mo 14.11.11 17:51 
Hallo Zusammen,

ich habe eine Datenbank mit ca. 900.000 Datensätzen im SQL-Server angelegt. Die Daten frage ich in einer C# Anwendung via Linq to SQL ab. Bei Eingabe einer Kundennummer erhalte ich i.d.R. mein Ergebnis auch in einer Sekunde.

Zusätzlich wollte ich mir jetzt noch die Anzahl der gespeicherten Datensätze anzeigen lassen. Diese Auswertung erfolgt einmalig beim Programmstart. Hier erhalte ich jetzt einen Connection-Timeout. (Dass ich den Connection-Timeout einstellen kann weiß ich.)

Auch als ich direkt im SQL-Server in einer View sämtliche Datensätze zählen wollte (Count(*)), dauerte es relativ lange, bis ein Ergebnis erschien. Jeder weitere Lauf lieferte dann sofort das Ergebnis.

Kann mir jemand einen Tip geben, wie man Aggregatfunktionen über eine große Anzahl von Datensätzen optimal erstellt? Eine Idee wäre z.B., die Anzahl der Datensätze über eine Funktion im SQL-Server abzufragen.

Oder einfach Connection-Timeout hochsetzen und warten bis Ergebnis kommt?

Gruß

Frank
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 14.11.11 18:30 
Hallo Frank,

ein reines COUNT(*) sollte eigentlich recht zügig gehen. Verwendest du noch eine WHERE-Bedingung dabei? Bei einem Projekt hatte ich auch mal das Problem, daß dort die Abfrage
ausblenden SQL-Anweisung
1:
SELECT COUNT(*) FROM <table> WHERE <column> is null					

bei mehr als 1 Mio-Datensätzen fast eine Minute gedauert hat.

Für diesen Beitrag haben gedankt: Oppi35
Oppi35 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 95
Erhaltene Danke: 3



BeitragVerfasst: Di 15.11.11 13:13 
Hi Th69,

vielen Dank für Deinen Tip.

Nach Deinem Beitrag habe ich mir mal den geloggten SQL-Befehl angeschaut, der an die Datenbank gesendet wurde.
80% von dem was da angefordert wurde, brauche ich gar nicht:)

Allein durch die LoadWith<> Methode hatte ich dann einen riesen Performance-Vorteil.

Nur allein für den Count Befehlt wurde die gesamte Tabelle mit 900.000 Datensätzen abgefragt.

Nachdem ich jetzt im SQL-Server eine Funktion angelegt habe, die das zählen der Datensätze übernimmt, läuft die Abfrage auch mit where-Bedingung zügig.
Viele Grüße

Frank
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 15.11.11 14:45 
Wie genau sah denn deine Linq-Query aus? Das hört sich schon sehr merkwürdig an.

_________________
>λ=
Oppi35 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 95
Erhaltene Danke: 3



BeitragVerfasst: Di 15.11.11 20:43 
Meine Struktur besteht aus Mastertabelle mit aktuell ca. 10 Datensätzen und einer Detailtabelle mit den besagten 900.000 Datensätzen.

In der beschriebenen Abfrage benötige ich lediglich die Daten der Mastertabelle. Aus der Datailtabelle benötige ich in dieser Abfrage nur die Anzahl der Spalten.

Wenn ich die Anzahl der Datensätze über Linq to SQL abfrage, wird lt. Log-Datei die komplette Detailtabelle in den Speicher geladen mit "Select Spalte1, Spalte2,...".
Nachdem ich jetzt die Anzahl der Datensätze über eine SQL-Function abfrage, entfällt die lange Abfrage via Linq to SQL.

Die Abfrage lautete:
Table<Mastertable> master=context.GetTable<Mastertable>();

und die Auswertung der Anzahl der Datensätze:
int countDatensätze=master.detail.count;


Ein Problem besteht allerdings noch:
Wenn ich die Anzahl der Datensätze das erste Mal abfrage, dauert es noch realtiv lange, bis das Ergebnis kommt. Ich habe per Taskmanager mal den Arbeitsspeicher bei der Aktion beobachtet. Der SQL-Server schreibt bei der ersten Ausführung des Count-Befehls eine Menge Daten in den Arbeitsspeicher. Danach bleibt die Arbeitsspeicherauslastung des SQL-Servers nahezu unverändert. Die Abfrage läuft bei jeder weiteren Abfrage zügig durch. Im Internet habe ich schon gelesen, dass der Count-Befehl bei großen Datenbanken arbeitsintensiv ist. Allerdings habe ich hierfür noch keine Lösung gefunden.
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Di 15.11.11 22:36 
Hi,
das mit der Arbeitsspeicherauslastung hört sich irgendwie danach an, dass alle Daten aus der Datailtabelle geladen werden, und dann ein Count ausgeführt wird. Hast Du Dir mal die Query angeschaut, die zur Datenbank geschickt wird?

Kenne das Ganze nur zu gut vom Entity Framework. Dort hat man zwei Interfaces, die bei der Abfrage zur Ausführung kommen können: IQueryable und IEnumerable.

IQueryable wird direkt in SQL-Syntax umgestzt und zur Datenbank geschickt - IEnumerable holt erst die Daten aus der Datenbank und führt dann den Enumerator aus...

Soll heißen, wenn man nicht genau aufpasst, so kann es auch mal passieren, dass man ungewollt die Daten aus der DB lädt.
LG