![]() |
Datenbank: MySQL • Version: 5 • Zugriff über: ZeosLib 7
Effiziente SELECT Abfrage
Hallo,
ich stricke gerade mit Datenbanken rum, eher gesagt mit MySQL 5. Es handelt sich um die Datenbank eines Spieleservers und normalerweise greift ein Java-Programm auf diese zu, nun wollte ich allerdings auch mal versuchen, sie aus Delphi heraus zu verwalten.
Delphi-Quellcode:
Da die Datenbank frisch eingerichtet wurde, enthält sie nur den Account "admin". Dieser wird mir durch Showmessage auch angezeigt, allerdings möchte ich nun gerne machen, dass mir die üblichen Felder angezeigt werden (id, passwort etc.), aber eben nur von einem bestimmten Account. Ich könnte einfach alle Accounts durchgehen (falls mal irgendwann mehrere vorhanden sind), allerdings gibt es da sicherlich eine bessere Lösung, oder?
ZConnection1.Connected := True;
ZQuery1.SQL.Text:='Select * from accounts;'; ZQuery1.Open; while not ZQuery1.Eof do begin Showmessage(Zquery1.FieldByName('name').AsString); ZQuery1.Next; end; Ich hoffe ich bin im richtigen Forum, denn diese Frage hat eher mehr direkt mit MySQL zu tun als mit Delphi... |
Re: Effiziente SELECT Abfrage
Vereinfachte Syntax des SQL-Befehls SELECT:
SQL-Code:
In deinem Fall also etwa sowas:
SELECT [Feldname1, Feldname2, ...] FROM [Tabelle] WHERE [Bedingungen]
SQL-Code:
Ich würde dir aber empfehlen, wenn du neu in der Arbeit mit Datenbanken bist, ein Tutorial oder sowas durchzuarbeiten. SQL ist eine eigene Sprache mit nicht geringem Funktionsumfang.
SELECT (id, password, ...) FROM accounts WHERE name = 'admin'
[edit=alzaimar] "code"- durch "SQL"-Tags ersetzt. Mfg, alzaimar[/edit] |
Re: Effiziente SELECT Abfrage
Zitat:
|
Re: Effiziente SELECT Abfrage
Mpf, da hast du natürlich recht. Danke für die Berichtigung.
Und für die Zukunft merke ich mir auch, dass es hier Tags für SQL-Code gibt. |
Re: Effiziente SELECT Abfrage
Ah danke, so geht es nun:
SQL-Code:
Ich hatte sowas ähnliches auch schon versucht, aber mit diesen anderen Hochstrichen (`), mit den "normalen" aus Delphi funktioniert es aber nun.
SELECT id FROM accounts WHERE name = 'admin';
|
Re: Effiziente SELECT Abfrage
Zitat:
Delphi-Quellcode:
Query.SQL.Text := 'SELECT id, password FROM accounts WHERE name = :name';
Query.ParamByName('name').Value := 'admin'; |
Re: Effiziente SELECT Abfrage
Zitat:
|
Re: Effiziente SELECT Abfrage
Über das Format, Quoting etc. musst Du Dir bei Parametern keine Gedanken machen. Als Nebeneffekt schützen Sie außerdem vor SQL-Injection, wobei ich jetzt erst nachdenken müsste, ob diese bei Verwendung von Format() möglich wäre.
|
Re: Effiziente SELECT Abfrage
Wenn Du z.B. in einer Schleife 10x die selbe Abfrage ausführen musst, nur mit unterschiedlichen Parametern, dann muss die DB das Statement nur 1x parsen und prüfen und dann beim Ausführen nur die Werte des parameters ändern. Kann u.U. einen erheblichen Geschwindigkeitsvorteil bringen.
|
Re: Effiziente SELECT Abfrage
Danke für die Infos. Da werd ich in Zukunft mal auf die Parameter umsteigen :)
|
Re: Effiziente SELECT Abfrage
Ein sehr sinnvolles Vorhaben.
Ich habe eine Anwendung übernommen, wo überhaupt nicht mit Parametern gearbeitet wurde. Insbesondere bei Schnittstellen, wo 1000x ein Insert ausgeführt wird, habe ich festgestellt, dass es nach umstellung auf Parameter um den Faktor 3 schneller lief. Da haben einige Leute erstaunt geschaut :mrgreen: Und so stelle ich nun Stück für Stück den gesamten Code auf Parameter um. |
Re: Effiziente SELECT Abfrage
Zitat:
|
Re: Effiziente SELECT Abfrage
Zitat:
|
Re: Effiziente SELECT Abfrage
Zitat:
Danke, Christoph |
Re: Effiziente SELECT Abfrage
Ja, da bei prepared Statement zu einem nur die Parameter übertragen werden und zudem das Parsen, Planbilden usw. entfällt
|
Re: Effiziente SELECT Abfrage
Zitat:
Delphi-Quellcode:
Danke+Gruß,
function TmyADOFunctions.ADOInsertIntoDB(a_SQLStatement: string): TMyADOResultStruct;
var myADOResultStruct : TMyADOResultStruct; lCounter : integer; begin assert(true = Prod_Conn_CorrectConnected); myADOResultStruct := TMyADOResultStruct.Create; // init try ADOCommand1.Connection.BeginTrans; ADOCommand1.CommandType := cmdText; ADOCommand1.CommandText := a_SQLStatement; ADOCommand1.Connection.Execute(a_SQLStatement, lCounter); myADOResultStruct.counter := lCounter; ADOCommand1.Connection.CommitTrans; myADOResultStruct.status := true; except // wenn Fehler abbrechen... on E: Exception do begin ADOCommand1.Connection.RollbackTrans; myADOResultStruct.status := false; myADOResultStruct.exception := E; myADOResultStruct.exceptionTxt := E.Message; end; end; // try-except Result := myADOResultStruct; end; Christoph |
Re: Effiziente SELECT Abfrage
Parameter zu verwenden bedeutet aber nicht sofort daß es zu einem prepared Statement wird - das muß die Datenbank-API erstmal unterstützen und dann heißt es doch eher Query.ExecPrepared oder nich?
|
Re: Effiziente SELECT Abfrage
Einmalig ( beim Ersten Insert oder bei Programmstart) Statement setzen und preparieren.
Beim Insert dann nur noch Parameter setzen. Zitat:
Zitat:
|
Re: Effiziente SELECT Abfrage
Zitat:
Danke! |
Re: Effiziente SELECT Abfrage
Einen Faktor 100 bekommst du wenn du die extended Syntax für INSERTs benutzt (die soweit ich weiß nur von MySQL unterstützt wird):
Code:
Du bastelst also einen riesigen SQL String zusammen und fügst damit tonnenweise Zeilen mit einem einzigen Befehl in die Tabelle. Ist limitiert auf die max_allowed_packet Einstellung (per Default auf 1M).
INSERT INTO `mytable` (`col1`, `col2`, `col3`)
VALUES (1, 'bla', 'foo'), (2, 'bla', 'foo'), (3, 'bla', 'foo'), (4, 'bla', 'foo'), (5, 'bla', 'foo'), ... (1000, 'bla', 'foo') |
Re: Effiziente SELECT Abfrage
@anse: Tja, schade, hat mit ADO auf MS Access jedenfalls nicht geklappt. Merke ich mir aber, falls ich mal auf MySQL stoße.
|
Re: Effiziente SELECT Abfrage
Zitat:
|
Re: Effiziente SELECT Abfrage
Nö, eher noch zu tief. Es kommt natürlich auf die Anzahl der Zeilen an die man einfügen will - bei vielen "kurzen" Zeilen ist der Geschwindigkeitsvorteil durch Wegfall des Overheads enorm, dagegen bei längeren Zeilen weniger. Probier es aus :)
|
Re: Effiziente SELECT Abfrage
Intern wird das auch als prepared Staement abgehandelt. So groß dürfte der Overhead auch nicht sein.
|
Re: Effiziente SELECT Abfrage
Zitat:
Am besten ist natürlich die Kombination aus beiden: Prepared Statements + Bulk-Insert :mrgreen: |
Re: Effiziente SELECT Abfrage
Zitat:
Naja, wir kommen glaube ich vom eigentlichen Thema ab :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:00 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 by Thomas Breitkreuz