![]() |
Datenbank: MS SQL 2005 • Version: Express • Zugriff über: ADO
SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
Moin zusammen,
mich würde mal interessieren, wie Ihr eure Anwendung in Bezug auf die SQL Verbingung programmiert bzw. einstellt. Zitat:
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:
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.
KeppConnecton: True
Datenübermittlung via TADODataSet 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 |
AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
Zitat:
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 ..)? Zitat:
|
AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
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) |
AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
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. |
AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
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 |
AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
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?
|
AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
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:
Für die weiteren Bereich ist es immer die gleiche Procedure, nur die Daten und die Tabelle ändert sich.
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;
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:
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 |
AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
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. |
AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
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. |
AW: SQL Server : Perfomanceprobleme - sinnvolle DB Verbindung gesucht
Zitat:
Das geht aber auch in einem Rutsch:
Code:
Somit benötigst du nur 1 Query, wo du bislang mehrere hast
INSERT INTO Tabelle1 ( fooa, foob ) VALUES ( :fooa, :foob );
INSERT INTO Tabelle2 ( fooc, food ) VALUES ( :fooc, :food ); ... Ach ja ... wenn du Parameter öfter verwenden möchtest, dann so
Code:
Und wenn man sich ganz oft wiederholt (z.B. die Liste der installierten Software) und die Tabelle so aussieht:
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 ); ...
Code:
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.
Domain
Computer IP-Adresse Software
Code:
Das spart enorm Bandbreite, weil die Informationen zu Domain, Computer, IP-Adresse nur einmal übertragen werden und nicht x-mal
INSERT INTO Software (Domain, Computer, IP, Software )
SELECT :Domain, :Computer, :IP, Software FROM tempSoftware |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz