AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
Thema durchsuchen
Ansicht
Themen-Optionen

SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

Ein Thema von Piro · begonnen am 24. Feb 2011 · letzter Beitrag vom 24. Feb 2011
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Piro
Piro

Registriert seit: 14. Jul 2003
Ort: Flintbek
810 Beiträge
 
Delphi XE2 Professional
 
#1

SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 10:53
Datenbank: MS SQL 2005 • Version: Express • Zugriff über: ADO
Moin zusammen,

mich würde mal interessieren, wie Ihr eure Anwendung in Bezug auf die SQL Verbingung programmiert bzw. einstellt.

Zitat:
Mein SQL Server: 2 CPU's 2.66GHz mit 2GB RAM
Ich habe seit ein paar Tagen Performanceprobleme mit meinem SQL 2005 Express Server.

Morgens, wenn die Anwender sich am Computer anmelden, wird mein Programm ausgeführt, welches Computerinformationen über WMI ermittelt und in die SQL DB schreibt. Das Programm braucht normalerweise nicht länger als 30 Sekunden, um die Daten zu ermitteln und in die DB zu schreiben.

Es kann vorkommen, dass 500 Anwender gleichzeit Daten in die DB schreiben. In dieser Zeit ist der SQL Server an seinem Limit und hat längere bis ganz lange Antwortzeiten. Wenn die Stoßzeit des Anmeldens vorbei ist, ist er wieder performat.

SQL Einstellungen im Programm:
Code:
KeppConnecton: True
Datenübermittlung via TADODataSet
Sollte man eventuell auf TADOCommand umsteigen und mit Parameter arbeiten und ggf. prepare verwenden? Massendaten sind es aber eigentlich nicht. Wäre schön zu wissen, wie ihr das händeln würdet bzw. was ich noch optimieren könnte.

Des weiteren habe ich Programme, die die Informationen anzeigen für eine handvoll Anwender. Würdet ihr die SQL Verbindung immer wieder trennen nach einer DB Abfrage oder einmal öffnen und KeppConnection True lassen und erst mit dem Programmende die Verbindung schließen?

Ich habe das Gefühl, dass er die Resourcen nicht frei gibt, wenn ich die Verbindung mit SQLConnection.Close beendet im Programm. Erst wenn das ganz Programm geschlossen wird.

Wäre schön zu wissen, wie Ihr solche Anforderungen löst?

Vielen Dank im voraus und hoffe auf Eure Erfahrungen.

Sven
  Mit Zitat antworten Zitat
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
533 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 11:25
Es kann vorkommen, dass 500 Anwender gleichzeit Daten in die DB schreiben. In dieser Zeit ist der SQL Server an seinem Limit und hat längere bis ganz lange Antwortzeiten. Wenn die Stoßzeit des Anmeldens vorbei ist, ist er wieder performat.
Ist dann wohl wirklich ein SQL Server Performance Problem.
2005 Express ist auf eine CPU und 1GB Ram beschränkt.
Kann es sein dass dein Applikationsdesign suboptimal ist?
Bei einer Client-Server Anwendung könnte man die Daten z.b. cachen und dann gesammelt inserten.

Wie werden denn die Daten geschrieben (einzelne Inserts via Schleife, Transaktionen ..)?

Das Programm braucht normalerweise nicht länger als 30 Sekunden, um die Daten zu ermitteln und in die DB zu schreiben.
Wo wird "normalerweise" die Zeit gebraucht? Um die Daten zu ermitteln oder um diese in die Datenbank zu schreiben?
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.
  Mit Zitat antworten Zitat
jobo

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

AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 11:38
Ich hab schon lange nicht mehr mit SQL Server gearbeitet. Aus der ganzen ADO.Net Technik, Verbindungstrennung, lokale Datenhaltung, etc. pp. habe ich immer abgeleitet, dass es "best practice" ist, sprich MS das extra so designed hat, um seine Server zu schonen.

2 Gedanken unabhängig vom Server:
- WMI auszulesen könnte teilweise auch was hakelig sein, daher erst auslesen und komplett sammeln, im nächsten Schritt an den Server senden (falls es nicht schon so ist)
- Wie schreibst Du in die SQL DB? Mittels Dataset.insert, fieldbyname('field').value := xy … ?
Das wäre wahrscheinlich die ungünstigste Lösung. Geeigneter wäre einzelne, parametrierte Inserts via TADOQuery oder vielleicht auch komplette Batch Scripte, wenn es viele inserts sind.
Da weiß ich leider nicht, ob MS SQL via ADOQuery soetwas schluckt. (Vielleicht reicht es, einzelne Statements per ; zu trennen)
Gruß, Jo
  Mit Zitat antworten Zitat
EarlyBird

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

AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 11:53
wenn es um schnellen Datentransfer auf den SQL-Server geht kann ich dir die TMSLoader Komponente von Devart empfehlen.
(ist in den "SDAC Professional Edition components" enthalten)
Damit habe ich sehr gute Erfahrungen gemacht.
Für mich hat sich die Investition gelohnt.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#5

AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 11:54
bei SQL-Express, Vorschlag
wenn der Umfang es erlaubt eine Prozedur schreiben die alle Parameter "schluckt", nachdem diese gesammelt wurden und die Connection nur so lange wie nötig offen halten
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.196 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 14:26
Wo genau hängt das Programm? Wie schreibst du die Daten in die DB? ich hoffe doch direkt mit parametrisierten "INSERT..."-Anweisungen bzw. SP's. Oder öffnenst du eine TADOTable und lässts erst mal die gesammte DB-Tabelle zum Client übertragen?
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Piro
Piro

Registriert seit: 14. Jul 2003
Ort: Flintbek
810 Beiträge
 
Delphi XE2 Professional
 
#7

AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 14:57
Also ich mach das so:

Ablauf:
1. WMI Daten in Records bzw. Arrays speichern (findet im Program lokal statt)
2. Records bzw. Arrays in die DB (jeweilige Tabelle) speichern
3. Programm beenden

Folgende Daten werden übertragen, die in der dazugehörigen SQL Tabelle sind:
1. Allgemeine Informationen
2. Arbeitsspeicher
3. Festplatten
4. Netzwerklaufwerke
5. Netzwerkinfos
6. Software
7. Hotfixes
8. Printer
9. Monitors

Folgende Komponenten verwende ich:
- TADOConnection
- TADODataSet
- TADOCommand (nur für das Löschen)

Folgende Prozeduren verwende ich:
z.B.: Allgemeine Infos
Delphi-Quellcode:
   DSData.Close;
   DSData.CommandText := 'Select id from computer where (computername='+QuotedStr(sysname)+') and (serial='+QuotedStr(serial)+')';
   DSData.Open;
   id := DSData.FieldByName('id').AsString;
   DSData.Close;

   if id <> 'then
   begin
     DSData.Close;
     DSData.CommandText := 'Select * from computer where id='+id;
     DSData.Open;
     DSData.Edit;
   end
   else
   begin
     DSData.Close;
     DSData.CommandText := 'Select * from computer';
     DSData.Open;
     DSData.Append;
   end;

   try
     DSData.FieldByName('computername').AsString := sysname;
     DSData.FieldByName('domain').AsString := BasicInfo.domain;
     DSData.FieldByName('manufacturer').AsString := BasicInfo.manufacturer;
     DSData.FieldByName('model').AsString := BasicInfo.model;
     DSData.FieldByName('serial').AsString := BasicInfo.serial;
     DSData.FieldByName('assetclass').AsInteger := BasicInfo.assetclass;
     ...
     DSData.POST;
Für die weiteren Bereich ist es immer die gleiche Procedure, nur die Daten und die Tabelle ändert sich.
Delphi-Quellcode:
for i := 0 to max_AMemory do
begin
  if AMemory[i].name = 'then
    break;

  DSData.Close;
  DSData.CommandText := 'Select * from computer_memory where sid = ' + id + ' and name = '+QuotedStr(AMemory[i].name);
  DSData.Open;

  if DSData.RecordCount > 0 then
    DSData.Edit
  else
    DSData.Append;

  DSData.FieldByName('name').AsString := AMemory[i].name;
  DSData.FieldByName('capacity').AsString := AMemory[i].capacity;
  DSData.FieldByName('speed').AsString := AMemory[i].speed;
  DSData.FieldByName('lastupdate').AsString := FormatDateTime('dd.mm.yyyy hh:nn:ss',lastupdate);
  DSData.FieldByName('sid').AsString := id;
  DSData.Post;
end;

// Alte Einträge löschen
SQLCommand.CommandText := 'delete from computer_memory where sid = ' + QuotedStr(id) + ' and lastupdate <> ' + QuotedStr(FormatDateTime('dd.mm.yyyy hh:nn:ss',lastupdate));
SQLCommand.Execute;
Zitat:
parametrisierten "INSERT..."-Anweisungen bzw. SP's
Habe ich damit wirklich einen Performancegewinn? Ich verwende das nur bei Massendaten. Da klappt es super aber ist, dass das gleiche, wenn ich immer wieder eine andere Tabelle anwählen muss. Dann brauche ich 8 x TADOCommand, oder?
Was sind SP's?

Leider kann ich nicht nur "EINEN" parametrisierten INSERT benutzen, da ich mehre Tabellen verwende. Das wäre echt gut. Aber naja. Es muss ja auch anders gehen.

Gruß, Sven
  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
 
#8

AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 14:57
Bei der Anzahl von Clients würde ich die nicht direkt auf den SQL-Server loslassen (schon weil der ja ganz klein ist).

Einfache Lösung (mit Hausmitteln zu erledigen):

FTP-Server einschalten und die Clients übertragen ihre Daten an den FTP-Server.
Ein kleiner Dienst überwacht den Ordner und pustet diese Daten dann in den SQL-Server rein.

Vorteile:
- Über den Dienst steuerst du die Auslastung des Servers (evtl. nur x Einträge pro Sekunde reinpusten)
- Nur eine Stelle (der Dienst) überträgt die Daten an den SQL-Server, Änderungen am DB-Layout sind somit ohne weiteres möglich
- Dienst abschalten und den SQL-Server warten/sichern - Die Clients werden trotzdem nicht beim Abladen gestört

Ach ja, so wie du das im Moment machst (Append, Post) ist zudem auch die langsamste aller Methoden.
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
Benutzerbild von Piro
Piro

Registriert seit: 14. Jul 2003
Ort: Flintbek
810 Beiträge
 
Delphi XE2 Professional
 
#9

AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 15:50
Coole Idee mit dem FTP Server & dem Dienst. Da denke ich mal mehr drauf rum.

Was wäre denn die beste Lösung ohne Append, Post? Parametrisierte INSERTs für die 8 Bereiche. Würde es gerne vorher einmal wissen bevor ich mir die Mühe mache, mein Programm anzupassen.
  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
 
#10

AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht

  Alt 24. Feb 2011, 15:56
Parametrisierte INSERTs für die 8 Bereiche. Würde es gerne vorher einmal wissen bevor ich mir die Mühe mache, mein Programm anzupassen.
Ja

Das geht aber auch in einem Rutsch:
Code:
INSERT INTO Tabelle1 ( fooa, foob ) VALUES ( :fooa, :foob );
INSERT INTO Tabelle2 ( fooc, food ) VALUES ( :fooc, :food );
...
Somit benötigst du nur 1 Query, wo du bislang mehrere hast

Ach ja ... wenn du Parameter öfter verwenden möchtest, dann so
Code:
SET @fooa = :fooa;
SET @foob = :foob;
SET @fooc = :fooc;
INSERT INTO Tabelle1 ( fooa, foob ) VALUES ( @fooa, @foob );
INSERT INTO Tabelle2 ( fooa, fooc ) VALUES ( @fooa, @fooc );
...
Und wenn man sich ganz oft wiederholt (z.B. die Liste der installierten Software) und die Tabelle so aussieht:
Code:
Domain
Computer
IP-Adresse
Software
dann macht es durchaus Sinn, nur die Spalte Software in eine temp. Tabelle auf den SQL-Server zu schieben und die dann an die Ziel-Tabelle anzuhängen.
Code:
INSERT INTO Software (Domain, Computer, IP, Software )
SELECT :Domain, :Computer, :IP, Software
FROM tempSoftware
Das spart enorm Bandbreite, weil die Informationen zu Domain, Computer, IP-Adresse nur einmal übertragen werden und nicht x-mal
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)

Geändert von Sir Rufo (24. Feb 2011 um 16:10 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 12:23 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