Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
SQL Select Anweisung - Performance verbessern
M-209
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

SQL Select Anweisung - Performance verbessern

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
michlG
myCSharp.de - Experte

Avatar #avatar-2909.png


Dabei seit:
Beiträge: 3.430
Herkunft: Naturns - Südtirol - Italien

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
M-209
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
demondriver235
myCSharp.de - Member



Dabei seit:
Beiträge: 496
Herkunft: Oldenburg

beantworten | zitieren | melden

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

EDIT:
Reicht nicht auch:

SELECT id FROM tbl_Tabelle WHERE ID > LastID ???
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von demondriver235 am .
"Programming is similar to sex. If you make a mistake, you have to support it for the rest of your life."
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.976

beantworten | zitieren | melden

Zitat
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?
private Nachricht | Beiträge des Benutzers
M-209
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

@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
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1.987
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
M-209
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

@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
private Nachricht | Beiträge des Benutzers
f_igy
myCSharp.de - Member



Dabei seit:
Beiträge: 115

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.976

beantworten | zitieren | melden

@M-209:
Zitat
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.
private Nachricht | Beiträge des Benutzers
M-209
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

Aber wird dabei nicht für jeden User der zur DB verbindet eine eigene Queue erstellt?
private Nachricht | Beiträge des Benutzers
xxxprod
myCSharp.de - Experte

Avatar #avatar-2329.gif


Dabei seit:
Beiträge: 1.378
Herkunft: Österreich\Wien

beantworten | zitieren | melden

Zitat von FZelle
@M-209:
Zitat
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
Zitat
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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von xxxprod am .
private Nachricht | Beiträge des Benutzers
M-209
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

@xxx

Genau das hab ich in Bezug auf die SqlDependency gemeint.



Zu dem Link: ich werd mir das mal durchsehen und auf jedenfall ausprobieren!
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.976

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
M-209
myCSharp.de - Member



Dabei seit:
Beiträge: 32

Themenstarter:

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15.853

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers