Laden...

SQL Select Anweisung - Performance verbessern

Erstellt von M-209 vor 11 Jahren Letzter Beitrag vor 11 Jahren 3.088 Views
M
M-209 Themenstarter:in
32 Beiträge seit 2011
vor 11 Jahren
SQL Select Anweisung - Performance verbessern

Liebe Community,

ich arbeite momentan an einem Projekt bei dem ich überprüfen muss ob neue Daten
in der Tabelle gespeichert werden. Hierzu habe ich einen ID und alle ID´s ( Auto - Increment Wert) die höher sind als der gespeicherte ID sind neue Datensätze. Jetzt möchte ich aber zu erst überprüfen ob überhaupt ein höherer ID vorhanden ist. Wenn nicht sollte die Funktion abgebrochen werden. Momentan dauert diese Funktion wenn keine neuen ID´s vorhanden sind 0,02 Sekunde.

Momentan lese ich die Daten mittels ExecuteScalar().

Das Select Statement sieht ca. so aus

SELECT COUNT(*) FROM tbl_Tabelle WHERE ID > LastID

Danach überprüfe ich ob ExecuteScalar einen Wert über 0 zurückgibt, wenn nicht, wird die Methode beendet.

Gibt es eine Möglichkeit, dass ich das ganze noch beschleunige?

Ich hoffe ihr versteht ungefähr was mein Problem ist und könnt mir evtl. helfen.

3.430 Beiträge seit 2007
vor 11 Jahren

Hallo M-209,

das klingt so als wolltest du mitbekommen ob sich was in der Tabelle geändert hat.
Wenn das der Fall ist (und du SQL Server) verwendest dann kannst du dir mal SQL Dependency anschauen.
Da wird dein Programm sozusagen Benachrichtigt wenn es in dieser Tabelle eine Änderung gab.

Ansonsten könntest du evtl. über einen Index beschleunigen.
Aber da du die ID vermutlich schon als Primary Key gesetzt hast dürfte dies nicht nötig sein

Grüße
Michael

M
M-209 Themenstarter:in
32 Beiträge seit 2011
vor 11 Jahren

Hi michlG,

danke erstmal für die Antwort.

Das mit den SQL Dependency hab ich schon probiert, ist aber für meine Anwendung nicht umsetzbar, da es zu viele Ressourcen verschlingt. Die Logik zum updaten ist schon implementiert, dass ist kein Problem. Ich möchte das ganze nur noch ein wenig beschleunigen.

PS: ID ist ein Primary Key

lg M-209

D
496 Beiträge seit 2005
vor 11 Jahren

Versuch mal statt count() max() zu benutzen.

EDIT:
Reicht nicht auch:

SELECT id FROM tbl_Tabelle WHERE ID > LastID ???

"Programming is similar to sex. If you make a mistake, you have to support it for the rest of your life."

F
10.010 Beiträge seit 2004
vor 11 Jahren

da es zu viele Ressourcen verschlingt.

Es ist eher so das das Pollen was Du machen willst die Resourcen verschwendet.

Was meinst Du wirklich wenn du das behauptest?

M
M-209 Themenstarter:in
32 Beiträge seit 2011
vor 11 Jahren

@FZelle:

Da es eine applikation ist, mit der später viele User gleichzeitig arbeiten, würde es, sofern ich es richtig verstanden habe für jeden User eine Queue erstellen und das erscheint mir sehr aufwendig.

Falls ich falsch liege bitte ich darum mich eines besseren zu belehren.

@demodriver235 ich kann deinen Vorschlag leider erst am Abend prüfen, aber ich werde es auf jeden Fall ausprobieren und dann eine Rückmeldung geben

T
2.219 Beiträge seit 2008
vor 11 Jahren

Kannst du neue Einträge nicht in der Datenbank einfach per Datenbank Feld als Neu markieren?
Das spart dir das suchen nach neuen IDs und vereinfacht deine Verarbeitung.

Dann musst du nur alle Einträge suchen, die ein entsprechendes Feld mit true haben.
Diese verarbeitest du dann und setzt die Felder eben auf false.

Deine aktuelle Suche wäre eher unperformant, da der Index auch nicht immer aktuell ist und somit die DB über alle Daten laufen müsste.
Deshalb wäre es ggf. einfacher mit einem extra Flag Feld zu arbeiten.

Alternativ solltest du mal schauen ob es nicht performanter wäre mit einem SqlDataReader zu prüfen ob Daten vorliegen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

M
M-209 Themenstarter:in
32 Beiträge seit 2011
vor 11 Jahren

@T-Virus:

Diese Möglichkeit hätte ich auch schon bedacht, aber es ist leider nicht möglich, da ja viele User gleichzeitig darauf zugreifen und wenn ein Flag vom einen Gesetzt wird dann bekommt ein anderer gar nicht mehr mit das er neu ist.

Zum Thema DataReader: Ich hatte es zuvor mit einem DataReader realisiert und da benötigte ich für die Funktion ca. 0.04 sek also doppelt so lange

Lg M-209

F
115 Beiträge seit 2012
vor 11 Jahren

Hi,

probier mal

SELECT MAX(ID) FROM tbl_Tabelle

und leg eine Index auf die ID (ist ja für uniquness eh ganz gut). Viele DB-Systeme werten dann nur noch den letzten Index-Eintrag aus, was in aller Regel sehr schnell geht.

Vergleichen musst Du dann natürlich im Code...

Gruß
f-igy

F
10.010 Beiträge seit 2004
vor 11 Jahren

@M-209:

Falls ich falsch liege bitte ich darum mich eines besseren zu belehren.

Ja, Du liegst falsch.
Gerade das ständige pollen ist deutlich resourcefressender als diese kleine Queue, bei der der Sql Server selber entscheiden kann wann er dich benachrichtigt.
Diese "Rückruf" Funktionalitäten sind gerade deshalb überhaupt in die verschiedenen Sql Server eingebaut worden.

M
M-209 Themenstarter:in
32 Beiträge seit 2011
vor 11 Jahren

Aber wird dabei nicht für jeden User der zur DB verbindet eine eigene Queue erstellt?

1.378 Beiträge seit 2006
vor 11 Jahren

@M-209:

Falls ich falsch liege bitte ich darum mich eines besseren zu belehren.
Ja, Du liegst falsch.
Gerade das ständige pollen ist deutlich resourcefressender als diese kleine Queue, bei der der Sql Server selber entscheiden kann wann er dich benachrichtigt.
Diese "Rückruf" Funktionalitäten sind gerade deshalb überhaupt in die verschiedenen Sql Server eingebaut worden.

Laut MSDN ist das aber nicht die empfohlene Vorgehensweise:

SqlDependency-Klasse

SqlDependency wurde zur Verwendung in ASP.NET oder in Diensten der mittleren Ebene entworfen, in denen eine relativ kleine Anzahl von Servern aktive Abhängigkeiten für die Datenbank aufweisen.Das Objekt wurde nicht für Client-Anwendungen entworfen, in denen für Hunderte oder Tausende Client-Computer SqlDependency-Objekte für einen einzelnen Datenbankserver eingerichtet sind.Wenn Sie eine Anwendung entwickeln, in der Sie zuverlässige Sub-zweite Benachrichtigungen erfordern, wenn Datenänderungen, die Abschnitte Planen einer effizienten Abfragebenachrichtigungsstrategie und Alternativen zu Abfragebenachrichtigungen im Planen für Benachrichtigungen Thema in der SQL Server-Onlinedokumentation überprüfen.

Und als Empfehlung dazu gibts auch einen Link auf der Seite: Planen von Benachrichtigungen

Lg, XXX

M
M-209 Themenstarter:in
32 Beiträge seit 2011
vor 11 Jahren

@xxx

Genau das hab ich in Bezug auf die SqlDependency gemeint.

Zu dem Link: ich werd mir das mal durchsehen und auf jedenfall ausprobieren!

F
10.010 Beiträge seit 2004
vor 11 Jahren

Naja, das Pollen zu regelmäßigen Zeiten mit der gleichen abfrage ist viel belastender.

Auch sollte man den betreffenden Artikel mal genau lesen, da geht es eher um komplexe Abfragen die berechnet werden müssen, nicht um "einfaches hinzufügen" von Daten.

Ich kann sagen das SqlDependency in einer recht großen Intranetanwendung zu deutlich geringerer Last am Server und viel besseren Antwortzeiten geführt hat, als das ständige pollen von 500 User vorher.

M
M-209 Themenstarter:in
32 Beiträge seit 2011
vor 11 Jahren

Also ich erkläre nochmal mein Problem genauer:

Ich arbeite an einer Multiuser Applikation die ähnlich wie der Explorer ( Dateisystem) arbeiten sollte, aber nur als DB im Hintergrund. Jetzt habe ich mir die Frage gestellt wie kann ich am vernünftigsten herausbekommen ob neue Datensätze in der Tabelle sind bzw. ob welche geändert worden sind. Anfangs wollte ich es mit SqlDependencys lösen, aber da ich davon ausgegangen bin, dass es für eine Multiuser Applikation nicht geeignet ist, habe ich diesen Lösungsansatz wieder verworfen.

Mein Lösungsansatz den ich jetzt verwende ist, dass ich für jeden Datensatz der geändert oder hinzugefügt wird, wird ein Eintrag in einer eigenen Tabelle erstellt. Diese Tabelle speichert dann welcher Datensatz geändert oder hinzugefügt wird. Ich überprüfe nun diese Tabelle ob neue Datensätze sind und falls nicht wird das Laden einfach beendet.

Ich weiß nicht ob diese Benachrichtigungen das richtige für mein Vorhaben sind, da ich ja in ziemlich kurzen Abständen bzw. ziemlich oft update.

Ich hoffe es wird jetzt klarer.

lg M-209

16.806 Beiträge seit 2008
vor 11 Jahren

WCF Service, der die SQDependency abonniert, Einträge verwaltet / cached und Aktualisierungen an alle Clients pusht.
Bzw. braucht er die Dependency gar nicht, da der WCF Service ja weiß, welche Einträge er aktualisiert / hinzufügt.

Wenn Du auf den SQL Server (und das ACID-Prinzip) nicht festgefahren bist lohnt sich evtl. dazu noch nen Blick auf nen anderes DB-System.
Ich verwalte Shares in einer MongoDB-Datenbank, um so schneller auf gewisse Dateistellen zugriffen bzw. diese hashen zu können. Aktualisierungen werden an andere WCF Instanzen direkt gepusht.