![]() |
AW: DB Tabelle beschleunigen
Tabellendefinition haben wir.
Es fehlen: Die Indexdefinitionen! Die auszuführenden SQLs! Ohne diese Angaben kann man nicht helfen, sondern nur rumspekulieren. Index erstellen: ![]() Grundlagen für SQL aneignen: Dringend. ![]() |
AW: DB Tabelle beschleunigen
Zitat:
|
AW: DB Tabelle beschleunigen
Zitat:
|
AW: DB Tabelle beschleunigen
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
Mit der ersten Abfrage hole ich mir den letzten Auftrag des Artikels, der beendet wurde und in der zweiten hole ich mir die Maschineninformationen. Die erste Query mache ich, weil sich Angaben zur Geschwindigkeit (in oaagbz) der Maschine von Zeit zur Zeit ändern. Also hole ich mir damit den letzten Stand.
procedure TMySQLDB.Get_Alternativen(ArtikelNr, Bereich: string);
var I: integer; where1: string; Cols: TCols; Rows: TRows; begin where1:=''; FMySelectQuery.SQL.Clear; FMySelectQuery.SQL.Add('select max(a.waaunr) from as400archiev as a '+ 'where a.watenr=:artikel '+ 'and left(a.oamanr,2) in (SELECT arbeitsplatzkz from bereiche '+ 'where bereiche_text= :bereich ) '+ 'group by a.oamanr '); FMySelectQuery.ParamByName('artikel').AsString:=ArtikelNr; FMySelectQuery.ParamByName('bereich').AsString:=Bereich; ExecQuery(FMySelectQuery, Cols, Rows,0); if FMySelectQuery.RecordCount=0 then begin SetLength(FRows_Alternativen, Length(FCols_Alternativen),0); Exit; end; for I := 0 to Length(Rows[0]) -1 do begin if I=0 then where1:=where1+QuotedStr(Rows[0,I]) else where1:=where1+', '+QuotedStr(Rows[0,I]) end; FMySelectQuery.SQL.Clear; FMySelectQuery.SQL.Add('select oamanr, mamabz, oaagbz from as400archiev '+ 'where waaunr in ('+where1+') '+ 'and left(oamanr,2) in (SELECT arbeitsplatzkz FROM bereiche '+ 'where bereiche_text=:bereich) '+ 'group by oamanr' ); FMySelectQuery.ParamByName('bereich').AsString:=Bereich; ExecQuery(FMySelectQuery, FCols_Alternativen, FRows_Alternativen,0); end; Zitat:
Vielen Dank Patrick |
AW: DB Tabelle beschleunigen
Hallo,
MySQL multi-column indices ![]() Laut der Tabellen-Beschreibung ist der Index in der richtigen Reihenfolge. Und einen separaten Index hatte der TE auch schon probiert, hatte aber auch nichts geholfen. |
AW: DB Tabelle beschleunigen
Hallo,
Indexdefinition = Welche Indizes gibt es. select max(a.waaunr) from as400archiev as a where a.watenr=:artikel and left(a.oamanr,2) in (SELECT arbeitsplatzkz from bereiche where bereiche_text= :bereich ) group by a.oamanr Das in (also das SubSelect) könnte bei MySQL zu Problemen führen, wenn der SQL-Server das für jeden einzelnen Datensatz ausführt. Mach mal 2 Queries draus, hole dir mit Query1 die arbeitsplatzkz und benutze das Ergebnis Query2 (Select max). SubSelects ![]() MySQL müsste auch einen Planalyzer haben, der einen Query-Plan erzeugt, also sagt, wie der DB-Server intern eine Query abarbeitet. Wenn dann z.B. bei SELECT arbeitsplatzkz from bereiche where bereiche_text= :bereich steht natural scan, muss die komplette Tabelle durchlaufen werden, um das Ergebnis zu bekommen. Liegt ein Index auf bereiche_text, würde der die Suche beschleunigen. Zu meinen Fragen: 1.9 Sekunden bei Select* und Select ein_Feld. Tja, ein Planalyzer könnte dir jetzt sagen, ob die Query-Ausführung (Execute) langsam war, oder das Übermitteln der Daten über das Netz (Fetch). Ohne einen Planalyzer könntest Du deine Anwendung auch auf dem SQL-Server mal selber laufen lassen. Dann ist der Netzeinfluss erst mal weg. |
AW: DB Tabelle beschleunigen
SQL-Code:
Zuerst: wielange dauert das?
select max(a.waaunr) from as400archiev as a
where a.watenr = :artikel and left(a.oamanr,2) in (SELECT arbeitsplatzkz from bereiche where bereiche_text = :bereich) group by a.oamanr
SQL-Code:
SELECT arbeitsplatzkz from bereiche where bereiche_text = :bereich
Wie lange dauert es, wenn Du einen Index auf bereiche_text erstellst? Funktioniert das? Wird es schneller?
SQL-Code:
Alternativ:
select max(a.waaunr) from as400archiev a, bereiche b
where a.watenr = :artikel and left(a.oamanr,2) = b.arbeitsplatzkz and bereiche_text = :bereich group by a.oamanr
SQL-Code:
Alles nur ungetestet hingedaddelt.
select max(a.waaunr) from as400archiev a
inner join bereiche b on left(a.oamanr,2) = b.arbeitsplatzkz where a.watenr = :artikel and b.bereiche_text = :bereich group by a.oamanr Sowas
SQL-Code:
in 'ner Wherebedingung ist nicht gerade dafür bekannt, dass entsprechende Abfragen schnell werden, in der Regel schließt sowas eine Indexnutzung aus.
left(a.oamanr,2)
Auch ein
SQL-Code:
in einer Wherebedingung ist nicht zwingend zur Beschleunigung einer Abfrage geeignet, eher das Gegenteil.
in (select spalte from tabelle)
Achso: Und einfache Abfragen sind das ganz und gar nicht, die Schwierigkeit einer Abfrage ergibt sich nicht daraus, ob es schwierig ist sie zu schreiben, sie zu formulieren, sondern daraus, wie schwierig ihre Ausführung für die Datenbank wird. Schlimmste Laufzeitannahme: Wenn Deine Tabelle 2.5 Mio Datensätze hat und Du per left(a.oamanr,2) für jeden Datensatz eine Einschränkung baust, so muss die Datenbank 2,5 Mio mal eben diesen Substring bilden. Und dann muss sie 2.5 Mio mal dieses SQL
SQL-Code:
ausführen, obwohl es eigentlich immer das gleiche Ergebnis liefert.
SELECT arbeitsplatzkz from bereiche where bereiche_text = :bereich
Dann muss sie sich alle die Sätze merken, bei der die Bedingung zutrifft und anschließend davon den Satz mit der größten waaunr je oamanr auswählen. Für meine Begriffe sind bei dem Aufwand die Antwortzeiten ja eigentlich garnicht mal so übel ;-) |
AW: DB Tabelle beschleunigen
Zitat:
|
AW: DB Tabelle beschleunigen
Zitat:
Momentan ist aber noch unklar, was ein Index überhaupt ist. |
AW: DB Tabelle beschleunigen
Zitat:
Ansonsten ist vieles, wie schon in anderen Antworten gesagt, von der spezifischen Query abhängig. Die besseren Datenbanken bieten eine query plan analyzer an, mit dem man sich mal ansehen kann, wie der query optimizer sich das Vorgehen vorstellt und was er da Zeitbedarf abschätzt. Da kann man normalerweise sofort sehen, ob vorhandene Indizes verwendet werden oder der Optimizer auf einen full table scan ausweicht (schlecht, sehr schlecht!). Es hängt auch von der Art der Query ab, ob die Datenbank schon Records zurückliefern kann, bevor der volle Resultset verfügbar ist. Sowas wie "distinct", "group by" oder "order by" in der query machen das unmöglich (es sei denn, ein order by kann direkt über einen Index realisiert werden). Verwendung von Funktionen in einer WHERE-Klausel (wie concat, upper, cast, etc.) machen es unmöglich, für den Zugriff einen Index auf dem betroffenen Feld zu verwenden, selbst wenn einer existiert. Außerdem sind select * Abfragen Gift für die Performance, wenn man eigentlich nur einen Teil der Spalten braucht. Sowas erhöht einfach das Datenvolumen, was den Speicher des Servers belastet und die Datenübertragung zum Client bremst. Außerdem sollte man immer im Hinterkopf behalten, dass auch Abfragen bei den meisten DB Servern in Transaktionen laufen und damit Serverresourcen belegen, bis die Abfragen geschlossen und die zugehörige Transaktion committed wurde (glücklicherweise macht das Client framework das normalerweise, wenn man eine Query schließt). Viele Abfragen offenzuhalten ist daher etwas, mit dem man sich weder bei DB Admins noch bei den Benutzern beliebt macht :wink:. Leider macht das typische Delphi RAD Design genau das... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:31 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