-
Before-Trigger => du hast noch die Chance (falls erlaubt bei externen Triggern) Daten zu manipulieren um Constraints zu befriedigen (setzen Primary Key, Laden Fremdschlüssel, u.ä.)
After-Trigger => wird erst aufgerufen, wenn alle Contraints (Unique Key/Index, Not Null,Check, Ref ...) positiv beschieden sind. Eine Änderung der Daten ist nicht mehr zugelassen.
Beim SQL-Server hat man da eben keine Chance, deshalb wird dort häufig der Einsatz von Prozeduren für Insert/Update empfohlen. Was allerdings nicht unerheblichen Mehraufwand bedeutet und die Unterstützung von EF erschwert.
Wird beim After-trigger dann doch noch ein Update gemacht, wird dann bei tatsächlichen Änderungen des aktuellen Satzes noch die "Satzversionen" für die Transaktionen aktiviert werden.
Häufig wird dann auch noch vergessen, dass ja durchaus mehr als 1 Zeile betroffen wurde.
-
So, ich habe jetzt auf unsererm Testsystem die Zeit für die Anzahl Sätze pro Stunde aus dem ersten Programmteil (nur Insert der Schlüsselwerte und einer Differenz aus 2 Werten aus der Basisdatei) ermittelt.
- Ohne Trigger werden hier ca. 10,8 Mio Sätze/Stunde eingefügt (6,1 Mio. in 34 Min)
- mit Trigger werden nur 1,5 Mio Sätze/Stunde geschrieben.
Der Insert erfolgt als 1:1 Kopie:
create trigger MIVGES000U after insert on MIVGES00 referencing new as nnn for each row mode db2sql
insert into ANALYSES.ANTRD0000T values(nnn.MGFIRNUM,
nnn.MGKUNNUM,
nnn.MGFILNUM,
nnn.MGVERNUM,
nnn.MGKFZNUM,
nnn.MGKFZART,
nnn.MGKFZGRU,
nnn.MGBERGRU,
nnn.MGUMSGES,
nnn.MGUMS001,
nnn.MGUMS002,
nnn.MGUMS003,
nnn.MGUMS004,
nnn.MGUMS005,
nnn.MGTAGGES,
nnn.MGBERSTD,
nnn.MGDATICO,
nnn.MGTIMICO,
nnn.MGDATICI,
nnn.MGTIMICI,
nnn.MGKILGEF);
label on trigger MIVGES000U is 'Trigger: MIVGES00 insert';
Die Schlüsselwerte sind nnn.MGFIRNUM, nnn.MGKUNNUM, nnn.MGFILNUM.
nnn.MGKILGEF beinhaltet die Differenz vom Kilometerstand checkout und checkin also die gefahrenen Kilometer.
Alle anderen Spalten sind blank oder 0, auch MGDAT* und MGTIM*, Datum und Uhrzeiten sin nummerisch definiert.
-
Da ist es immer schwer eine Vorhersage zu machen.
Fakt ist, dass die Anzahl der Writes sich mindestens halbieren muss, da sie ja verteilt werden.
Nun hängt es von weiteren Faktoren ab, wie sich die IO's verteilen.
- Satzlänge und damit die Anzahl gepufferten Writes
- Speicherort auf dem Plattenarray (ggf. sind beide Dateien physisch auf derselben Disk)
Aber immherhin ist das nicht Faktor 60 sondern nur 7.
Und wie sieht die Aufgabenstellung aus?
Muss die Kopie bei Masseninsert durchden Trigger erfolgen oder reicht ein folgender "insert into ... select from ..."?
Letzteres kann durchaus effektiver sein, da nur blockweise gelesen werden muss während beim Insert mehrere Aktionen stattfinden:
- Satznummer aus der Kette der gelöschten ermitteln
- Falls keine gelöschten, ggf. Datei erweitern
- Satz schreiben
-
 Zitat von Fuerchau
Da ist es immer schwer eine Vorhersage zu machen.
Fakt ist, dass die Anzahl der Writes sich mindestens halbieren muss, da sie ja verteilt werden.
Nun hängt es von weiteren Faktoren ab, wie sich die IO's verteilen.
- Satzlänge und damit die Anzahl gepufferten Writes
- Speicherort auf dem Plattenarray (ggf. sind beide Dateien physisch auf derselben Disk)
Aber immherhin ist das nicht Faktor 60 sondern nur 7.
Und wie sieht die Aufgabenstellung aus?
Muss die Kopie bei Masseninsert durchden Trigger erfolgen oder reicht ein folgender "insert into ... select from ..."?
Letzteres kann durchaus effektiver sein, da nur blockweise gelesen werden muss während beim Insert mehrere Aktionen stattfinden:
- Satznummer aus der Kette der gelöschten ermitteln
- Falls keine gelöschten, ggf. Datei erweitern
- Satz schreiben
Bulk Operationen haben unter günstigen Bedingungen einen erheblich höheren Durchsatz wie satzweise Operationen. Zur Blockung beim lesen kommen noch Blockung beim schreiben, geändertes Sperrhandling, Optimierung beim Zugriff. Der Trigger erzwingt satzweise Verarbeitung, die mit ca 500 Operationen/sec durchaus plausibel erscheint.
Ähnliche Leistung wie bei Bulk Operationen erzielt man bei satzweiser Verarbeitung allenfalls bei massiver Parallelisierung.
D*B
-
In diesem Fall reicht ein nachträglicher insert into... select from...
Jedoch macht mir der Datendurchsatz bei den geplanten History-Tabellen Bauchschmerzen.
Bei den einzelnen Aufträgen (Auftragserfassung/-änderung) ist das noch kein Problem, da im Max nur 2-3 Sätze hinzugefügt oder aktualisiert werden.
Jedoch kann es auf die Fakturierung auswirkungen haben.
Die oben genannten Werte habe ich übrigens auch schon mit den CASE WHEN... Funktionsaufrufen erreicht. Die Funktionen wurden ja durch die CASE-Bedingung nicht aufgerufen.
CASE WHEN... hat also keine großen Auswirkungen.
Das 60-fache war im gesamten Programmablauf aufgekommen. Hier spielt der Update-Trigger die größere Rolle, da dieser pro Satz mehrfach ausgelöst wurde (das Programm ist optimierungswürdig )
Das 7-fache bei einem reinen Insert ohne Manipulationen ist schon nicht akzeptabel.
-
Nun, dann kommt ggf. der Update ON EACH STATEMENT doch noch zum Tragen.
Dann kannst du in diesem Fall den "insert ... select .... from inserted" als Bulkinsert codieren.
Allerdings weiß ich nicht, ob durch die temporäre Inserted-Table und den dadurch zusätzlichen Write die Performance da wirklich besser ist.
Bei deinem später noch geplanten Update wird dann auch noch die Indexoptimierung gravierend.
-
Vielleicht auch noch ein paar Gedanken:
* was hat die Tabelle beim Attribut REUSEDLT hinterlegt? (DSPFD)
Bei *NO wird immer am Tabellen-Ende hinzugefügt.
Bei *YES sucht er den nächsten freien Platz
* Hast du schon den DB-Monitor gestartet?
Wieviele "Hard-Open" zur Tabelle gemacht?
Falls er (aus was für einen Grund auch immer) öfters ein Hard-Open machen muss, stimmt was grundsätzlich nicht.
* Schon probiert mit Commitment Control zu arbeiten?
Also das ATOMIC weg lassen und im aufrufer Programm Commit Steuerung aktivieren.
Dann läuft der Trigger im gleichen Isolation Level wie der Aufrufer.
Hat den Vorteil dass man sich I/O ersparen kann wenn man am ende erst ein COMMIT absetzt und dadurch mit größeren Blöcken auf die Disk schreibt.
* Probier mal MODE DB2ROW statt DB2SQL
lg Andreas
-
Journalisierung erhöht die IO's und ändert am Blocken nichts.
Laut Doku wird DB2ROW ignoriert und sowieso DB2SQL verwendet.
-
Dem mit Commit wiederspreche ich!
Mit Commit können die IO's nachweislich verringert werden.
Denn das System schreibt dann nach dem Commit mit Blöcken auf die Disk.
Ohne Commit (*NONE) wird für jedes INSERT einzeln geschrieben.
Ich würde sogar sagen, dass du mit Commitsteuerung die meiste Performance hier herausholen könntest.
-
 Zitat von andreaspr@aon.at
Dem mit Commit wiederspreche ich!
Mit Commit können die IO's nachweislich verringert werden.
Denn das System schreibt dann nach dem Commit mit Blöcken auf die Disk.
Ohne Commit (*NONE) wird für jedes INSERT einzeln geschrieben.
Ich würde sogar sagen, dass du mit Commitsteuerung die meiste Performance hier herausholen könntest.
... commit bei Bulk Operationen ist fatal, da werden Millionen von Sperrren eingesammelt und beim eventuellen Rollback geht die Kiste in die Knie. Journalisierung kann durchaus positive Wirkungen haben, da dann die sequentiellen Schreiboperationen auf die Receiver vorgezogen werden, die kaum Strom kosten - wenn denn die Hardware Bilanz das zulässt.
Im vorliegenden Fall, wenn ich denn die rudimentäre Problembeschreibung richtig verstehe, ist der Trigger das vorrangige Problem, da selbiger die Bulk Operation zur satzweisen Verarbeitung zwingt.
Aus meinen Erfahrungen sehe ich zwei mögliche Strategien:
- Sequenz von Bulk Operationen (hierbei sollte man prüfen, ob man für inserts alle Indexe auf delayed stellt und im nachhinein parallel wieder hochzieht - kann helfen aber auch massiv schaden)
- Batch Änderungen massiv parallel reinfahren - dann aber mit Commit wg. Collisions.
Generell gilt hier: es gibt keine Patentrezepte, sondern nur Arbeitshypothesen, die sorgfältig evaluiert werden müssen.
D*B
-
 Zitat von BenderD
Im vorliegenden Fall, wenn ich denn die rudimentäre Problembeschreibung richtig verstehe, ist der Trigger das vorrangige Problem, da selbiger die Bulk Operation zur satzweisen Verarbeitung zwingt.
Deshalb war mein Vorschlag die Commitsteuerung übergreifend zu aktivieren und das ATOMIC weg lassen.
Wenn ich mit Commit um ein vielfaches schneller bin, ist die Bilanz auch im Falle eines ROLLBACK immer noch weit im grünen Bereich.
 Zitat von BenderD
Generell gilt hier: es gibt keine Patentrezepte, sondern nur Arbeitshypothesen, die sorgfältig evaluiert werden müssen.
So ist es!
Gerade wenn es um Performance geht, ist Commit ein wichtiger Bestandteil der leider viel zu oft unterschätzt wird.
Similar Threads
-
By linguin in forum NEWSboard Programmierung
Antworten: 11
Letzter Beitrag: 10-08-17, 12:51
-
By Isabella Pridat-Zapp in forum Archiv NEWSboard Events
Antworten: 0
Letzter Beitrag: 10-09-15, 12:50
-
By Sebastian85 in forum NEWSboard Programmierung
Antworten: 10
Letzter Beitrag: 11-03-15, 07:26
-
By B.Hauser in forum IBM i Hauptforum
Antworten: 3
Letzter Beitrag: 08-02-02, 17:18
-
By Frank Pusch in forum IBM i Hauptforum
Antworten: 3
Letzter Beitrag: 17-05-01, 09:34
Tags for this Thread
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks