View Full Version : SQL Update
andreaspr@aon.at
01-03-10, 14:18
nur der neugier halber, sind das sql-tabellen gewesen?
nein, ganz 'normale' DDS PF und LF
andreaspr@aon.at
01-03-10, 14:55
ok danke, dann ist eh alles klar.
wenns sql-tabellen wären würde es nämlich auch schneller laufen.
Dem kann ich nicht zustimmen.
Mit PF's und LF's läuft es fast immer genauso schnell wie mit SQL-Tabellen.
Wichtig sind einzig und allein vorhandene Indexe und ob sie identische Definitionen haben.
Identisch heißt hier wirklich identisch. Packed und Zoned ist dem RPG nämlich egal, der schiebt dann Umwandlungen ein, SQL aber nicht.
Manchmal ist es hilfreich, den Key auf der linken Seite per cast anzupassen, also
decimal(a.Key, n, y) = b.key
oder
zoned(a.key, n, y) = b.key
Das funktioniert auch mit ungleich langen Zeichenfeldern:
cast(a.key as char(nn)) = b.key
Und zu guter letzt:
LF's mit Select/Omit werden komplett ignoriert!
In früheren Releases führte allein die Existenz einer solchen LF zur Verwendung der CQE.
Hallo Robi,
ist zwar schon vorbei, aber folgendes wäre evtl. auch gegangen:
update DATEI2 a set Jahr = coalesce((select Dec(substr(datum, 1, 4)), Jahr) from DATEI1 b where a.key1 =
b.key1)
dann spart man sich den EXISTS.
(Ich mag die coalesce-Funktion einfach, vor allem wegen dem Namen...)
Gruß, Christian
dann spart man sich den EXISTS.
(Ich mag die coalesce-Funktion einfach, vor allem wegen dem Namen...)
Gruß, Christian
@Christian
Nur solltest Du dabei berücksichtigen, dass bei der Verwendung von EXISTS nur die Datensätze, für die die Bedingung zutrifft geändert werden, während bei der Verwendung von COALESCE ALLE Datensätze geändert werden. Im Klartext heißt das, dass der Datensatz gelesen und unverändert wieder (physisch) geschrieben wird. Wenn Du also eine große Datei hast und nur wenige Sätze ändern willst, kann die Performance schon ganz schön in den Keller gehen, vor allem wenn man berücksichtigt, dass man auf Satz-Sperren (bzw. entsprechende Wartezeiten) beim Lesen von Datensätzen, die man eigentlich nicht ändern will laufen kann.
Birgitta
@Baldur
Manchmal ist es hilfreich, den Key auf der linken Seite per cast anzupassen, also
decimal(a.Key, n, y) = b.key
oder
zoned(a.key, n, y) = b.key
Das funktioniert auch mit ungleich langen Zeichenfeldern:
cast(a.key as char(nn)) = b.key
Bringt allerdings bei Joinen von ungleichen Feldern wenig bis gar nichts! Ein Index kann (zumindest) vor Release 6.1 nur verwendet werden, wenn das Original-Feld unverändert ist. Die Verwendung von CAST oder einer skalaren Funktion bewirkt, dass das Original-Feld verändert wird. Die Länge spielt dabei keine Rolle!
Allerdings kann durch die explizite Konvertierung Einfluss darauf genommen werden kann, welche Datei "führend" verarbeitet wird und mit der anderen Datei verknüpft wird. Für die Datei, bei der die Original-Felder verwendet werden, kann ein Index verwendet werden. Für die andere Datei kann allenfalls ein Teilschlüssel verwendet werden.
Ansonsten konvertiert SQL intern selber (zumindest seit V5R3)!
Natürlich sollten z.B. in Where-Bestimmungen immer die gleichen oder compatible Datentypen verwendet werden. Wenn also z.B. das Feld Kunden-Nr. alphanumerisch ist, die Kunden-Nr. in diesem Feld jedoch numerisch ist, kann man das folgende angeben:
Where KundeNr = 4711
Der Datensatz wird gefunden, allerdings muss für jeden zu lesenden/vergleichenden Satz eine Konvertierung vorgenommen werden, um identische Datentypen zu vergleichen zu können, was Performance kostet.
Birgitta
andreaspr@aon.at
02-03-10, 07:12
Dem kann ich nicht zustimmen.
Mit PF's und LF's läuft es fast immer genauso schnell wie mit SQL-Tabellen.
Wichtig sind einzig und allein vorhandene Indexe und ob sie identische Definitionen haben.
Identisch heißt hier wirklich identisch. Packed und Zoned ist dem RPG nämlich egal, der schiebt dann Umwandlungen ein, SQL aber nicht.
bin mir jetzt nicht sicher ob wir das gleiche meinten.
meine aussage bzgl. der geschwindigkeit bezog sich nur auf den zugriff mit sql auf sql-tabellen vs. dds-tabellen.
dass rpg dds-tabellen oft schneller verarbeiten kann als über sql ist klar.
wir haben in der firma auch oft probleme, wenn via sql auf dds-tabellen zugegriffen wird. ändere ich diese auf sql-tabellen, läuft es viel schneller.
denn im ersten fall wird die CQE verwendet und im zweiten die SQE, welche gegenüber der CQE zb auch threads parallel abarbeiten kann.
meine aussage bzgl. der geschwindigkeit bezog sich nur auf den zugriff mit sql auf sql-tabellen vs. dds-tabellen..
Das liegt daran, dass beim Schreiben in SQL Tabellen geprüft wird, ob der angekommene Inhalt gültig ist, während beim Lesen aus SQL-Tabellen keine Gültigkeitsprüfung erfolgt. Bei DDS beschriebenen Dateien erfolgt die Gültigkeitsprüfung erst beim Lesen, während jeder Schrott in die Dateien geschrieben werden kann. Dadurch ist das Lesen aus SQL Tabellen (etwas) schneller als das Lesen aus DDS beschriebenen Dateien, während das Schreiben (etwas) langsamer ist.
dass rpg dds-tabellen oft schneller verarbeiten kann als über sql ist klar...
RPG kann zumindest bei der ersten Ausführung Dateien (unabhängig ob DDS oder SQL) schneller verarbeiten als SQL, da RPG in RPG ein Zugriffsweg vorgegeben wird (F-Bestimmungen) währen SQL grundsätzlich optimiert auch und vorallem dann wenn eine DDS beschriebene logische Datei angegeben wird.
wir haben in der firma auch oft probleme, wenn via sql auf dds-tabellen zugegriffen wird. ändere ich diese auf sql-tabellen, läuft es viel schneller.
denn im ersten fall wird die CQE verwendet und im zweiten die SQE, welche gegenüber der CQE zb auch threads parallel abarbeiten kann.
Es ist ein verbreiteter Irrtum, dass die SQE nur SQL-Tabellen verarbeiten könnte, während alle DDS Dateien von der CQE verarbeitet werden müssen. Die SQE kann DDS beschriebene physische Dateien verarbeiten.
Wird in einem SQL-Statement eine DDS beschriebene logische Datei angegeben, wird das SQL-Statement von der CQE ausgeführt, da die logische Datei aufgelöst wird (Feld-Auswahl, Select/Omit und Joins) und das SQL-Statement basierend auf der physischen Datei oder SQL Tabelle neu geschrieben wird. Dies Auflösung kann nur von der CQE vorgenommen werden (SQE steht schließlich SQL Query Engine).
Liegen auf der physischen Datei (oder SQL Tabelle) logische Dateien mit SELECT/OMIT-Anweisungen, wird auch bei Angabe der physischen Datei die Ausführung des SQL-Statements von der CQE übernommen. Der Grund dafür liegt darin, dass alle vorhandenen Zugriffswege also auch diejeningen, die in DDS beschriebenen logischen Dateien mit SELECT/OMIT hinterlegt sind verwendet werden sollen.
Ändert man in der Abfrage-Options-Datei QAQQINI die Option IGNORE_DERIVED_INDEXES auf *YES (*NO ist Unterlassungswert vor Release 6.1 mit Release 6.1 wurde der Unterlassungswert auf *YES geändert), werden Zugriffswege in DDS-beschriebenen Dateien ignoriert und das SQL-Statement kann von der SQE ausgeführt werden. Im Extremfall kann man sich durch diese Option Zugriffswege unter den Füßen wegziehen, so dass anstatt eines Index Access ein Table Scan oder zumindest eine Table Probe erfolgen muss.
Birgitta
Wichtig ist immer die Größenordnungen nicht aus dem Auge zu verlieren:
- Hauptspeicheroperationen dauern < Mikrosekunden (Millionstel Sekunden), hierzu gehören Prüfungen beim lesen/schreiben
- Datenbank Operationen dauern Millisekunden (Tausendstel), hierzu gehören reads, updates, open/close
- Zugriffspfad Berechnungen dauern einige Millisekunden
- Aufbau von temporären Zugriffspfaden kann Minuten dauern
Wenn man also Minuten sucht, scheidet da einiges aus, weil es im untersuchten Fall zu selten auftritt, oder zu kurz andauert.
Im vorliegenden Beispiel sind mit hoher Wahrscheinlichkeit unterschiedliche Zugriffspläne die Hauptursache. RLA macht in jedem Fall positioned Updates (der kann nämlich nix anderes), SQL hat sich, so wie es aussieht, für searched Updates entschieden - und die sind sehr viel langsamer (typischer Wert: Faktor 2).
(Der Vollständigkeit halber sei noch angemerkt, dass alle angegebenen zeitlichen Werte von der konkreten Hardware abhängen, die Verhältnisse zueinander aber durchgängig gelten)
D*B