![]() |
Datenbank: MySql • Version: 5.1 • Zugriff über: Unidac
Prozedur (SQL-Statement) optimieren
Hallo,
habe folgende Prozedur, welche nach dem hinzufügen des zweiten JOINS sehr langsam ist. Wo gibt es Optimierungsmöglichkeiten?:
Delphi-Quellcode:
Danke ...
procedure Tdata.getCatalog(var ioList : TDocxDocument; inList : TStringList; language : integer=1);
var i : integer; tmp : TDocxline; begin ioList.Clear; if workQuery.Active then WorkQuery.Active := false; workQuery.SQL.Clear; workQuery.SQL.Add('SELECT ass.level, ass.article_id, ass.additional_position, ass.mcount, ass.img, trans.name, art.number, art.type FROM '); workQuery.SQL.Add('assignments as ass JOIN articles as art ON ass.article_id=art.id JOIN translations as trans ON trans.article_id=art.id WHERE'); workQuery.SQL.Add('trans.language_id=:lng AND ass.id=:id'); for i := 0 to inlist.Count - 1 do begin workQuery.ParamByName('id').AsInteger := StrToInt(inList[i]); workQuery.ParamByName('lng').AsInteger := language; workQuery.Open; if not workQuery.IsEmpty then begin tmp.level := workQuery.FieldByName('level').AsInteger; tmp.article_id := workQuery.FieldByName('article_id').AsInteger; tmp.additional_position := workQuery.FieldByName('additional_position').AsInteger; tmp.mcount := workQuery.FieldByName('mcount').AsInteger; tmp.img := workQuery.FieldByName('img').AsString; tmp.article_name := workQuery.FieldByName('name').AsString; tmp.article_number := workQuery.FieldByName('number').AsString; tmp.article_type := workQuery.FieldByName('type').AsString; ioList.AddRange(tmp); end; workQuery.Close; end; end; |
AW: Prozedur (SQL-Statement) optimieren
Sind alle Schlüsselfelder indiziert?
|
AW: Prozedur (SQL-Statement) optimieren
@DeddyH
Du meinst, ob diese einen Index haben? Bisher nicht! |
AW: Prozedur (SQL-Statement) optimieren
In der where-Bedingung zuerst die Abfrage mit der kleinsten Ergebnismenge aus der Haupttabelle. Da in deinem Fall nur eine where-Bedingung auf die Haupttabelle geht, diese also zuerst abfragen. Dadurch werden nur noch Unterabfragen zu den resultierenden Datensätzen durchgeführt. Bei deiner Reihenfolge der where-Bedingung werden praktisch alle Datensätze der Haupttabelle angefasst um zu prüfen ob in Tabelle translations ein gesuchter Eintrag existiert.
Delphi-Quellcode:
Die Felder ass.id, art.id und trans.article_id sollten zusätzlich noch indiziert sein.
workQuery.SQL.Add('where ass.id=:id and trans.language_id=:lng');
|
AW: Prozedur (SQL-Statement) optimieren
Uuups, da wird die gnaze Sache direkt mal 80% schneller.
Danke! |
AW: Prozedur (SQL-Statement) optimieren
80% sieht doch nach einem Fortschritt aus!
Ich wollte nur anmerken, dass MySQL sicher soetwas wie einen Explain Plan zu den Abfragen anbietet. |
AW: Prozedur (SQL-Statement) optimieren
Zitat:
Nunja jedes DBMS ist anders. Gruß K-H |
AW: Prozedur (SQL-Statement) optimieren
Zitat:
Und man muss sich nicht soviel merken. :) |
AW: Prozedur (SQL-Statement) optimieren
Hi, gebe allen anderen Recht... Habe allerdings noch ne Idee, wie du die verarbeitung besser machen könntest...
Delphi-Quellcode:
procedure Tdata.getCatalog(var ioList : TDocxDocument; inList : TStringList; language : integer=1);
var i : integer; tmp : TDocxline; flevel, farticle_id, fadditional_position : TField; begin ioList.Clear; if workQuery.Active then WorkQuery.Active := false; workQuery.SQL.Clear; workQuery.SQL.Add('SELECT ass.level, ass.article_id, ass.additional_position, ass.mcount, ass.img, trans.name, art.number, art.type FROM '); workQuery.SQL.Add('assignments as ass JOIN articles as art ON ass.article_id=art.id JOIN translations as trans ON trans.article_id=art.id WHERE'); workQuery.SQL.Add('trans.language_id=:lng AND ass.id=:id'); for i := 0 to inlist.Count - 1 do begin workQuery.ParamByName('id').AsInteger := StrToInt(inList[i]); workQuery.ParamByName('lng').AsInteger := language; workQuery.Open; flevel := workQuery.Fields[0]; farticle_id := workQuery.Fields[1]; fadditional_position := workQuery.Fields[2]; //.... if not workQuery.IsEmpty then begin tmp.level := flevel.AsInteger; tmp.article_id := farticle_id.AsInteger; tmp.additional_position := fadditional_position.AsInteger; //.... ioList.AddRange(tmp); end; workQuery.Close; end; end; |
AW: Prozedur (SQL-Statement) optimieren
Hi,
danke für eure Tipps. Was ich mich noch Frage ist, ob man an dieser Stelle direkt lieber nen dynamisches INT-Array nehmen sollte:
Delphi-Quellcode:
damit dieses dauernde StrToInt wegfällt. Das wäre aber nen tieferer Eingriff:?
workQuery.ParamByName('id').AsInteger := StrToInt(inList[i]);
Viele Grüße ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:19 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