Vom TABLE OF TYPE zum REF CURSOR Performance-Tuning in einer bestehenden Anwendung Sebastian Lauff & Thies Rubarth DOAG Regionaltreffen Hamburg/Nord 16. September 2014 Ausgangssituation Anwendungsarchitektur bei Berenberg: • DB-Zugriff über generierte Java-Klassen • Business-Logik komplett in der DB (PL/SQL-Packages und –Types) • Java-Client mit (fast) reiner Anzeigefunktion • Java-Server übersetzt zwischen PL/SQL und XML Problem: • Anzeigen von großen Datenmengen sehr langsam 2 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR Datenlesen IST-Stand XML PL/SQL Analyse-Ergebnis: SQL 3 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR • PL/SQL-Overhead sehr teuer • Erstellen, übertragen, parsen des XMLs sehr teuer OPTIMIERUNG DB-TEIL Vorher - Die PGA bekommt einen dicken Bauch und der Anwender einen dicken Hals Alte Implementierung: • Selektierung aller IDs • Loop und jeweils den Type zu einer ID erstellen • Type in Table of Types zwischenspeichern • Gesamte Table of Types zurück geben 5 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR Type → Selektiert sich selbst → Selektiert andere Types → Selektiert Stammdaten über PL/SQL Cache Nachher – Lass die SQL Engine die Arbeit machen Neue Implementierung: • GUI Datensatz soweit wie möglich in SQL nachbauen • Kapselung der Anzeigelogik in einer View • 6 Weniger Joins benutzen • Stammdaten über Scalar Subquery Selects mit PL/SQL Result Cache • Dadurch Predicate Pushing ermöglichen 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR Codebeispiel PL/SQL Result Cache • Session übergreifender RESULT_CACHE bei Funktionen • Oracle 11gR2 erkennt automatisch die Abhängigkeiten zur Tabelle / zu den Tabellen Scalar Subquery Caching • SELECT FROM DUAL als Subquery erstellt einen Cache für das einzelne Select -> Der Aufruf an PLSQL wird im spezifischen Select nur einmal pro ID durchgeführt 7 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR Codebeispiel Predicate Pushing • Die WHERE Bedingung wird im Optimalfall auf der richtigen Tabelle ausgeführt, und es wird nicht die komplette View ermittelt und dann gefiltert HINT Nutzung bei Views • Angabe des Tabellenalias aus der Viewdefinition notwendig 8 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR Codebeispiel Function Return RefCursor • Record definieren • Ref Cursor definieren • Function bauen Weitere Möglichkeit: • Arbeiten mit %ROWTYPE statt Record 9 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR OPTIMIERUNG JAVA-TEIL Datenlesen SOLL-Stand SQL 11 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR Datenlesen - Implementierung Client FrameworkCode AnwendungsCode Dialog IncrementalReader Table (Model) JMS Singleton EJB Queue IncrementalGet IncrementalWorker Stateful EJB DataProvider JBoss 12 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR Singleton EJB DB Optimierungsergebnis im Prototyp 13 Nr. ALT (1541 Sätze) NEU (1541 Sätze) NEU (10000 Sätze) 1 847ms 195ms 838ms 2 857ms 178ms 874ms 3 887ms 220ms 814ms 4 854ms 224ms 789ms 5 845ms 182ms 814ms 6 853ms 223ms 818ms 7 879ms 180ms 794ms Ø 860ms 200ms 820ms 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR IHRE ANSPRECHPARTNER Peter Ruser Sebastian Lauff Business Analyst Core Banking IT/Organisation +49 40 350 60-8192 [email protected] Oracle Consultant (extern) IT/Organisation +49 40 350 60-8465 [email protected] Joh. Berenberg, Gossler & Co. KG Neuer Jungfernstieg 20 20354 Hamburg 14 16.09.2014 Vom TABLE OF TYPE zum REF CURSOR