CMD_DWH_Kurzreferenz_V3

Werbung
Data Warehouse Technik im Fokus - Skripte in Kurzform
1 /41
Oracle Data Warehouse
Kurzreferenz
Skripte, Systemabfragen und Empfehlungen
Stand Juni 2013 V4 (03.10.2013)
Document1
Data Warehouse Technik im Fokus - Skripte in Kurzform
Zu dieser Skriptesammlung
5 Allgemeiner Umgang mit Tabellen
Allgemeine Hilfen
6
Einrichten und Einstellen einer Testumgebung
6
Mess-Einstellungen + allgemeine Settings in SQLPlus
6
Gelöschte Tabellen endgültig löschen
6
Ausschalten der Recyclebin-Funktion
6
Speicher leeren
6
SELECT-Ausgabeformatierung
6
Systemparameter abfragen
6
Dictionary-Views auslesen
6
Ändern der Berücksichtigung Groß-/Kleinschreibweise bei Logon 6
SQL Plus
6
Metadaten-DDL für Objekte aus dem Dictionary generieren lassen
6
Enterprise Manager
6
Aufruf im Browser z. B. mit
Starten der Console
Wenn es mal klemmt
6
6
6
Datenbank, Listener und BS-Variablen
6
Starten der Datenbank
Listener starten und Status abfragen
Erreichbarkeit einer Datenbank über SID-Abfrage
6
6
6
Beispielumgebung
7
7
Skript –Tabellen OLTP-System
7
Beispiel-Star Schema
7
Vergleichs-Demo-Umgebung Steckbrief
7
Skript Fakten-Tabelle
7
Skript Kunden-Dimension
7
Skript Artikel-Dimension
8
Skript Regionen-Dimension
8
Skript Zeit-Dimension
8
Skript Vertriebskanal-Dimension
8
Skript Unique Keys für die Dimensionstabellen [nicht nötig] 8
Skript Bitmap-Indexe auf FK-Felderder Fakten-Tabelle F_UMSATZ
8
Skript Drop Bitmap Indexe
8
Skript Primary-Key-Felder auf Dimensions-Tabellen [nicht
nötig]
8
Skript Dimensional Table D_ARTIKEL
8
Skript Dimensional Table D_Region
8
Skript Dimensional Table D_Zeit
8
Skript Dimensional Table D_Kunde
8
Beispielabfragen auf das Beispiel-Star Schema
9
Beispielabfrage 1a Generische Abfrage auf vorgenanntes StarSchema
9
Beispielabfrage 1b Einfache Abfrage Summe Umsatz an einem Tag 9
Beispielabfrage 1c Summe Umsatz an einem Tag und
Vertriebskanal
9
Beispielabfrage 2 Einschränkungen über alle Dimensionen
9
Beispielabfrage3 (Ein-/Ausschalten Where-Argumente /Test Star
Query
9
Beispielabfrage 4: Top 3 Länder bezogen auf Einzelverkäufe 9
Beispielabfrage 5: Umsatz nach Quartalen
9
Beispielabfrage 6: Nach Umsatzstärke sortierte QuartalsRangfolge
9
Beispielabfrage 7:: Das umsatzstärkste Quartal pro Jahr
9
Beispielabfrage 8: Stärkster Umsatzmonat pro Bundesland
10
Beispielabfrage9: Top 10 Artikel bezogen auf Menge / Rank
/Subquery
10
Beispielabfrage9a: Top 10 Artikel bezogen auf Menge / Rank
/Subquery
10
Beispielabfrage10: -- Top 10 Artikel bezogen auf Umsatz in
einem Jahr
10
Beispielabfrage 11: - Top 3 Produkte je Produktgruppe sortiert
nach Rangfolge
10
Beispielabfrage 12: Die Top-Produktgruppe pro Bundesland
10
Beispielabfrage 13: Land mit dem stärksten Umsatz je
Produktgruppe
11
Beispielabfrage 14: Die Top und Flop Produktgruppe pro
Bundesland
11
Beispielabfrage 15: Die Top 2 Produktgruppen pro Bundesland 11
Beispielabfrage 16: Top/Bottom 2 Produktgruppen pro Bundesland
11
Beispielabfrage 17: Über Quartale kumulierte Umsätze pro Kunde
11
Beispielabfrage 18: Über Quartale kumulierte Umsätze pro Kunde
(Jahr + Kreis)
11
Beispielabfrage 19: Wieviel Prozent des Gesamtumsatzes pro
Land machen die 3 Top Produkte aus
12
Beispielabfrage 20: ¼ der Kunden tragen zu ? % des Umsatzes
bei?
12
Beispielabfrage21: Durchschnittliche Bestellquote eines Kunden
über 3 Monate?
12
Beispielabfrage 22: - CUBE
12
Beispielabfrage23 Vergleiche Umsätze mit Vorjahreszeitraum 12
Beispielabfrage 24 Year-To-Date. Kumulierung der Monatsumsätze
von Jahresbeginn an
12
Beispielabfrage 26 Verwendung von Grouping-Sets
12
Tabellen
Document1
14
14
Logging/Nologging-Modus für eine einzelne Tabelle ein/ausschalten
14
Allgemeine Informationen
14
Tabellengrößen und Platzverbrauch
14
Blick in die Column-Struktur einer Tabellen / Distinct Values
Nulls etc
14
Anlegen einer leeren Tabelle mit bestimmter Struktur
14
Anlegen von temporären Tabellen
14
Spaltennamen nchträglich ändern
14
Ungenutzten Platz freigeben und komprimieren
14
Blocknummern auslesen
14
Tablespace mit Datafile anlegen
14
Größe von Tabellen, Segmenten, Extents auslesen
14
Umgang mit Constraints
14
Abfragen auf bestehende Constraints im aktuellen Schema
Ausschalte / Einschalten von Constraints
14
14
Compression
14
Anlegen einer komprimierten Tabelle
Komprimieren eines Tablespace
Prüfen, ob Tabellen komprimierte sind
Tabellen und Partitionen komprimieren
Komprimierte Tabelle aus seiner unkomprimierten erstellen
Komprimierungsgrad für bestimmte Tabellen auslesen
14
14
14
14
14
14
Partitioning
Beispiel-OLTP Schema
2 /41
15
Wo und warum wird in dem Data Warehouse Partitioniert
15
Was wird partitioniert
15
Partitioning-Varianten
15
Skript Beispiel Range Partitioning Beispielskript
F_UMSATZ_RANGE
Skript zum schnellen Erstellen der Testtabelle aus F_UMSATZ
Skript Beispiel Range Partitioning Beispielskript
F_BESTELLUNG_RANGE
Beispielabfrage mit Einschränkung auf Zeit
MAXVALUE zum Aufnehmen von Werten ohne Zuordnung
Skript Beispiel Range Partitioning nach Alphabet
Erstellen Hash Partitioned Table au seiner anderen
Allgemeines Hash-Partitioning-Beispiel
Skript Beispiel Hash Partitioning und Tablespace-/DatafileZuordnung
Bitmap-Indexe auf Hash-partitionierte Tabelle
Drop Index
Skript Beispiel List Partitioning
Skript Beispiel für Sub-Partition (Range-List)
Beispielabfrage auf Range/List
Zweites Range/List – Beispiel
Skript Beispiel Reference Partitioning
Skript Beispiel Interval-Partition mit Monatspartitionen
Skript Beispiel Interval-Partition mit numerischer
Bereichsangabe
Ändern bestehender Range-Partition-Tables auf Interval
Partitioning
Skript Beispiel Virtuel Column Partition
Zuweisen unterschiedlicher Tablespaces
15
15
15
15
15
15
15
15
15
15
16
16
16
16
16
16
16
16
16
16
17
Abfragen auf Partitionen
17
Partitiondaten direkt abfragen
Grössen, Mengen und Namen
Verteilung von Partitionen auf Tablespaces
Tabellen,Partition,Rows
Tabellen,Partition,Rows,Blocks,MegaBytes
Partitionsgrenzen abfragen
Auslesen von Sub Partitions
Sich refenzierende Tabellen abfragen / Referen Partitioning
17
17
17
17
17
17
17
17
Verwaltung von Partitionen
17
Partionen hinzufügen
Partitionen auf anderen Tablespace verlagern
Merge von zwei Sub-Partitions
Ändern Defaults-Tablespace
Ändern der Werte bei List-Partitioning
Umwandeln einer Partion in eine Tabelle
Umbenennen einer Partition
Truncate einer Partition
Aufspalten einer Partition
Partition Exchange (Hinzufügen einer Tabelle als weitere
Partition)
17
17
17
17
17
17
17
17
17
Indexe
17
18
Wie und wo wird indiziert
Suche nachbestehenden Indexen
18
18
Suche nach Indexen bezogen auf eine bestimmte Tabelle
Status-Abfragen
Auflisten aller Indexe eines Schemas inkl. Größe
Auflisten aller lokalen Index
Anzeigen des Platzverbrauchs der Indexe
Beispiele für Definitionen (Bitmap / B*tree)
Behandlung von Indexen beim Laden
Rebuild Partitioned Index
Rebuild Sub-Partitioned Index
Verschieben eines Index auf einen anderen Tablespace
Aktualisierung der Index zusammen mit Tabellen-Updates
Einschalten Usage - Monitoring für einen Index
Welcher Index wurde tatsächlich genutzt: Usage - Abfrage
18
18
18
18
18
18
18
18
18
18
18
18
18
Data Warehouse Technik im Fokus - Skripte in Kurzform
Clustering Faktor und Anzahl Leaf-Blöcke abfragen
18
Partitionierung von Indexen
18
Skript Local Partion Index
18
Partitionierung der Indexe entsprechend der zugehörigen TablePartionen (Local Partiton Index) und zweisen unterschiedlicher
Tablespaces
18
Partitionierung des Index unabhängig von den Table-Partitionen
(Global Partition Index)
18
Partitionierte Indexe suchen
18
Rebuild lokaler Index
18
Rebuild Sub Partition Index
18
Verschieben auf anderen Tablespace
18
Star Schema
19
Allgemeine Regeln
Konsistenz, Mengen und Indexe im Star-Schema
19
19
Prüfen ob FK der Fakten-Tab in PK der Dimensionen
Größe der Indexe ausgeben
Index-Typen anzeigen
Größe aller Bitmap-Indexe
Star Transformation aktivieren
Menge der WHERE-Bedingungen überprüfen
19
19
19
19
19
19
Materialized Views
20
Hilfen/Konzepte für Materialized Views
20
Allgemeine Hinweise zur Definition von Materialized Views
Informationszugriffen planen und dokumentieren
Relevante Parameter
MVIEW suchen
Größe und Anzahl Zeilen von Mviews abfragen
Beispieldefinition MAV_Zeit_Umsatz
Beispieldefinition MAV_Artikel_Umsatz
Beispieldefinition MAV_Region_Umsatz
Beispieldefinition MAV_Kunde_Umsatz
Beispieldefinition MAV_Region_Artikel_Umsatz
Beispieldefinition MAV_Region_Zeit_Umsatz
Beispieldefinition MAV_Kunde_Zeit_Umsatz
Beispieldefinition MAV_Region_Zeit_Artikel_Umsatz
Beispiel-Definition
Beispiel für eine Partitionierte MAV
Definition Materialized View Log
Löschen Materilized View Log
Build Funktionen
Refresh Funktionen
Feststellen, ob PCT Tracking funktioniert
Refresh auf eine MAV
PMARKER Funktion
Komprimieren von Materialized Views
Refresh auf alle von einer Tabelle abhängigen MAVs
Aktualisieren aller Materialized Views
Anzeigen Materialized Views mit Zustand und View Logs
Anzeigen Materialized Views mit Zustand und PCT Regions
Stimmigkeit von Dimensionen prüfen
DBMS_MVIEW.Explain_mview
Auflisten von Dimension-Tables
Anzeigen der Struktur einer Dimensional Table
20
20
20
20
20
20
20
20
20
20
21
21
21
21
21
21
21
21
21
21
21
21
22
22
22
22
22
22
22
22
22
3 /41
Datenbank-Informationen, Version, Patchstände
24
Database-ID abfragen
Installierte Komponenten
Patchstand abfragen
Patch-Historie
Datenbankversion abfragen
24
24
24
24
24
User-Informationen / Einstellungen /Security
24
Welche USER gibt es in einer Umgebung und welchen Zustand
haben sie
24
Benutzer anlegen
24
Eigene Tabellen zum Lesen für alle freigeben
24
Allgemeine Benutzerinformationen abfragen
24
Ausschalten Expiration Date in Entwicklungs- und Test-Umgebung
24
Ändern des Lock-Zustads eines Users
24
Welche Rechte wurden einem User vergeben
24
Plattenplatz der Segment-Objekte eines Users
24
Logins pro User
24
User Platzverbrauch Tablespace
24
Maximale Parallelität von Benutzeraktivitäten
24
Tablespaces, Auflistungen, Mengen und Größen
24
Anlegen eines Tablespace mit Zuweisung eines Datafiles
Größe aller Data Files
Liste aller Tablespace mit Größenangaben
Temp-Space
Größe Redo Logs
Finden der größten Tabellen
Top 10 größten Tabellen eines Users
Data Files + Redo Logs + Temp
Freier Datenbank-Platz
Benutzter Datenbank-Platz
Belegter und benutzter Temp-Tablespace
Blockgrößen auslesen
Liste Tabellen und Berechnung der Größe in Byte, MB, GB
Tabellengrößen und Platzverbrauch
Größen und Mengen mit zusätzlichem Tablespace-Namen
Welche Objekte gehören zu einem Tablespace
Größenangaben bezogen auf Partitionen
Auflisten des Wachstums einzelner Tablespaces
Segment-Informationen
Gesamtauswertung belegter Plattenplatz und Freespace pro
Tablespace und Datafiles
24
24
24
24
24
24
24
24
24
24
25
25
25
25
25
25
25
25
25
Database Files
26
Auflistung aller Dateien
In welchen Datafiles liegen bestimmte Tabellen
Welche Tabellen liegen in einem bestimmten Data File
Single Block / Multi Block Reads
Database Files mit asynchronem Lesen und Schreiben
26
26
26
26
26
Lesestatistiken / Benutzungsverhalten
26
25
Gelesene und geschriebene Blöcke
26
Security
26
26
26
26
26
26
26
26
Memory-Cache
23
Benutzer anlagen
Ein Profil anlegen
Eine Rolle anlegen
Rollenrechte weitergeben
Default-Rolle einem Benutzer zuweisen
Rollen für einen Bnutzer aktivieren / deaktivieren
Was machen die Benutzer gerade
Tabellen in Cache legen / aus Cache entfernen
Welche Tabellen liegen im Cache
23
23
Laden des DWH
Query Result Cache
23
Schnelles Laden / Mengenbasiertes Laden
27
Aktivieren mit
Ausnutzen Result Cache durch Hint in der Abfrage
Abfragen auf im Cache befindliche Statements
Result-Cache-Memory-Report
Result Cache leeren
23
23
23
23
23
Parallelisierung
23
Grunsätzliches Schema für mengenbasiertes Laden
Direct Path Load
Insert ohne Log-Datei
Sequence-Objekt anlegen
Schnelles Schreiben CTAS (Create Table As Select)
Schnelles Löschen von Daten
27
27
27
27
27
27
Parallelisierung aktivieren
Automatisches Steuern mit
Eine einzelne Tabelle auf parallel” setzen
Parallelisierter Select-Zugriff
Prüfen welche Art der Parallelisierung eingestellt ist
Aktuelle SQL-Statements und deren Parallelisierung abfragen
23
23
23
23
23
23
Databas Link
27
Zugriff auf Remote-Oracle-Datenbank (Database Link)
Verwendung
27
27
Sequence für Zähl-Felder / Schlüssel aufbauen
27
Optimizer - Statistiken sammeln
23
Defintion eines Sequence-Objektes
Zugriff um den nächsten Zählerwert abzugreifen
Abfragen des aktuellen Stands
27
27
27
Statistiken für eine Tabelle
Statistiken für einen Index
Statistiken für eine Materialized View Definition
Statistiken für ein Schema
Automatische Aktualisierung für ein Schema einrichten
Automatisiertes Sampling
Abfrage ob automatisiertes Sammel aktiviert ist
Zustand/Aktualität der Statistiken abfragen
Zustand von Index-Statistiken abfragen
Histogramme abfragen
Histogramme sammeln
Abfragen der Grenzwerte der Histogram-Buckets
Löschen von Statistiken
Löschen von Histogrammen für einzelne Spalten
Markieren von Tabellen um inkrementelles Aktualisieren zu
ermöglichen
23
23
23
23
23
23
23
23
23
23
23
23
23
23
Trigger
27
Optimierung für schnelles Lesen
Umgebungsinformationen auslesen
Document1
23
24
23
27
Beispiel für einen Trigger (Insert,Delete,Update)
27
Text-Dateien Importieren
27
SQL Loader
Beispiel für Loader Control – File
External Table Beispiel
27
27
27
Directory-Objekte
27
Directory anlegen
Auflisten bestehender Directory-Definitionen
Logischen Directory-Name ändern
Name der Daten-(CSV-)Datei ändern
27
27
27
27
Datapump
27
Datapump - Beispiel mit Steuerdatei
Allgemeines Beispiel
Umändern des Default-Output-Directories
Datapump-Schätzung benötigter Plattenplatz
Datapump Data only Import
27
27
27
27
28
Data Warehouse Technik im Fokus - Skripte in Kurzform
Datapump Schema Mode
Datapump Network Mode
Interaktiver Modus mit CTRL C aktivierbar
Datapump und External Tables
28
28
28
28
Transportable Tablespace
28
4 /41
Sessions schnell ‘killen’
35
Schnelle Übersicht über aktuell laufende Sessions / wer / wo /
was
35
Verhindern von Memory Paging
35
Herausfinden Memory und Session
35
Transportable Tablespace-Verfahren
28
ASH (Active Session History), Session + User Informationen
35
Error Logging
28
Error Logging
Eindeutigkeitsprüfung ohne DML_Error_Logging
28
28
Regular Expressions
28
Regular Expression in Constraints verwenden
Umgang mit einzelnen Zeichen:
Bestehende Zeichengruppen
28
28
28
Größe ASH - Buffer
Session Daten abfragen
Die aktivsten SQLs in der letzten Stunde
Die aktivsten IO-Operationen
Sample-Time abfragen
Aktives SQL Abfragen
Übersicht über SQL-Statements in der Vergangenheit
Session-Informationen
35
35
35
35
35
35
35
35
SQL-Monitoring
35
Aus- und Einschalten aller Constraints
29
CASE in SQL-Statements / Manuelles Prüfen
29
IsNumeric-Prüfung
29
IsDate-Prüfung
29
Abhängigkeiten von anderen Feldern im selben Satz
29
Satzübergfreifendes Zusammenzählen von Feldwerten (analytische
Funktion)
29
Eindeutigkeitsprüfungen
29
Aggregatbildung und Bewerten von satzübergreifenden Summen 29
Foreign Key Prüfung
30
SQL Cache
Kurzabfrage auf ein bestimmtes Select-Statement mit einer
bestimmten Tabelle
SQL-Statistik abfragen / Wurde ein Ergebniss aus dem Cache
oder von der Platte gelesen?
Abfrage auf v$sql_Monitor
Feststellen welche Benutzer mit welchem SQL und welcher
Parallelität zugegriffen haben
SQLTun-Report über SQL ID aufrufen
Lese-Statistiken auf einzelne Tabellen gezielt abfragen
35
SQL-Mittel beim Laden
Planmanagement
36
Automatisiertes Sammeln von Plänen einschalten
Parameter zur Behandlung von Plänen
Nutzen der Pläne einschalten
Anzeigen von Plänen in Plan_Baselines - Eingeschränkt auf
einen User
Betrachten eines gespeicherten Plans
Evolve eines neuen Plans
36
36
36
Lese-Performance messen
37
Arbeiten ohne Constraints und mengenbasiertes SQL / Prüfen 29
30
Pivot/Unpivot Beispiele
30
Multiple Inserts /Manuelles Aufspalten von korrekten und nicht
korrekten Sätzen
30
Merge-Beispiel
30
36
36
36
36
36
36
36
37
37
Flashback
30
Log-Modus / Archiv-Modus prüfen
Aktuelle SCN abfragen
Retention-Zeit abfragen
Ändern Retention-Zeit
Abfragen der letzten Logs
Zurücksetzen einer Tabelle auf ältere SCN mit Flashback
Beispiel Flasback
30
30
30
30
30
30
30
Table Function
31
Record / Object - Definition
Definition einer Tabellen-Struktur
Table-Function-Definition
31
31
31
SQL / PL/SQL - Funktionen
31
Leeres PL/SQL-Function-Template
Numerische Funktionen
Stringfunktionen
Datum-Funktionen
Bedingte Abfragen (Decode / CASE)
Sonstige Funktionen
Konvertierungsfunktionen
Konvertierung von Datum in Zeichenkette (to_char) und
umgekehrt (to_date)
Zeitformat-Umwandlung
Konvertierung von Zahlen in Zeichenketten (to_char) und
umgekehrt (to_number)
31
31
31
31
32
32
32
Backup im Data Warehouse
32
32
Festeststellen des Log-Modus der Datenbank
39
Ein-(Aus-)schalten des Archivelog-Modus
39
Archive-Zustand anzeigen lassen
39
Wohin wird das Archive-Log geschrieben und wie groß ist die
Recovery Area
39
Wie voll ist die Recovery Area aktuell
39
Recovery Area vergrößern
39
32
Verwalten des Systems / Systembeobachtung 33
Anzeigen der gesetzten Schwellwerte für Alerts
Alerts abfragen
Alerts abfragen (historisch)
Alert-Datei-Ablage
Wait Classes abfragen
Wait Events
Menge der Undos
33
33
33
33
33
33
33
Informationen über die Session
33
Sortvorgänge auf Platte oder im Speicher
Session-Informationen
33
33
AWR (Analytic Workload Repository)
33
Einstellungen
Eingestellte Intervalle
Platzverbrauch AWR messen
Auflistung bestehender Snapshots
AWR-Snapshot manuell anlegen
Snapshot-Nummern ausfindig machen
AWR-Bericht erstellen
33
33
33
34
34
34
34
ADDM Informationen abfragen
34
Welche Informationen liegen vor
ADDM-Analyse starten
ADDM-Bericht anzeigen
Relevante Dictionary Views für Alerts und Session
34
34
34
34
Tracing
34
Trace-Output-Verzeichnis
Identifizierung einer zu prüfenden Session
Aktivieren des SQL-Trace
Deaktivieren
Beispiel-Trace-Session
Unleserlichen Trace-Output mit TKPROF formatieren
34
34
34
34
34
34
Session-bezogene Informationen
34
Session Daten abfragen
Größe SGA und entsprechende Speicherbereiche
Abfragen der idealen Memory-Ausnutzung
Abfragen der SGA / Welche Objekte sind im Speicher
34
34
34
34
Document1
Abschätzen Lesegeschwindigkeit (IO-Performancen)
Lesen einzelner Tabellen
bei dem
37
IO Messung / calibrate IO
37
Calibrate-Status abfragen
Calibrate IO abfragen
37
37
Perfstat
Orion
Lesestatistiken: Werden Daten genutzt?
37
37
38
39
Allgemeine Überlegungen
39
Argumente für ein DWH spezifisches Backup-Konzept
Was muss gesichert werden.
Wie wird gesichert
39
39
39
Archive Log
39
RMAN
39
RMAN starten
An Zieldatenbank einwählen
Welche Backups sind überflüssig
Welche Files benötigen ein Backup
Leeren Recover Area
Welche Files können nicht wiederhergestellt werden
Welche Sicherungen liegen vor
Alle Einstellungen von RMAN
Definieren eines Backup-Kanals
Flashback aktivieren
Verwendung der Recovery Area
Prüfen, ob Flashback aktiviert ist
Prüfung des benötigten Platzes
Retention-Zeit Flashback Area einstellen
Abfragen einer Tabelle von einem bestimmten SCN-Zustand
Abfragen einer Tabelle zu einer bestimmten Zeit
Tabellen mit Flashback zurückholen
Datenbank mit Flashback zurücksetzen (Kommandobeispiele)
Ältest mögliche Rückhol-Position feststellen
39
39
39
39
39
39
39
39
39
39
39
39
39
39
39
39
39
39
39
Anhang
40
(DWH-Administrations-Checkliste - wird aktualisiert)
Testdaten erstellen
40
40
SQL-Trigger-Tabelle für Dummy-FROM-Klausel erstellen
Tabelle mit laufender Nummer erstellen
40
40
Vorgehensweise bei der Erstellung der Demo-Umgebung
Hilfsprozeduren zu den Beispielmodellen
40
40
Zeitdimension
Daten in der Faktentabelle F_UMSATZ
40
41
Data Warehouse Technik im Fokus - Skripte in Kurzform
Zu dieser Skriptesammlung
Wem ist das nicht schon einmal passiert: Man entwickelt eine
PL/SQL-Prozedur zum Beschreiben einer Tabelle und hat die
Parameter für eine bestimmte Funktion vergessen.
Nachschlagen in der Doku: zu mühsam weil zu dick.
Nachschlagen im Handbuch: gerade verlegt.
Google’n: schon eher .... und und und...
Das ist Alltag von vielen Data Warehouse-Entwicklern: die
Dinge, die man nicht permanent anwendet, vergisst man. Diese
Sammlung von Skripten soll in dieser Situation etwas helfen:

Sie ist keine hochspezialisierte Sammlung von ExpertenSkripten, sondern sie fast einfache, alltägliche Lösungen
an einer Stelle zusammen, um sie schnell zur Hand zu
haben. Spezialwissen oder eine vollständige Beschreibung
von Kommando-Syntax: bitte in der Dokumentation nachsehen.
Diese Unterlage ersetzt nicht die Dokumentation.

Die Skriptesammlung legt ihren Fokus auf Data Warehouse –
Fragestellungen. Hierfür gibt es in der Tat einen Mangel
in der Lituratur aber auch bei „Google“, denn in der Regel
findet man eine Beschreibung von Funktionen und Features
quer über alle Anwendungsgebiete (OLTP, DWH) hinweg.

Die Sammlung enthält die wichtigsten Skripte und Kommandos
der Seminar-Reihe Data Warehouse Technik im Fokus, die bei
Oracle Deutschland schon seit 2006 regelmäßig angeboten
wird. Das in dieser Seminarreihe vermittelte Wissen ist
durchaus geeignet, um einen Mitarbeiter erfolgreich für
ein Data Warehouse Projekt vorzubereiten.

Die Skriptesammlung ist stellenweise kommentiert, um eine
Bewertung bzw. Orientierung für deren Anwendung im Data
warehouse – Umfeld mitzugeben.
Die der Skripte-Sammlung zu Grunde liegende Seminarreihe Data
Warehouse Technik im Fokus stellt Datenbank-Technologie nicht
beliebig vor, sondern sie bespricht zunächst eine idealisierte
Data Warehouse Architektur und ordnet die benötigten DatenbankFeatures den Erfordernissen in dieser Architektur unter. Dadurch
entsteht automatisch eine durch Data Warehouse-Anforderungen motivierte
Fokussierung bei der Datenbank-Technologie.
Die Sammlung orientiert sich an einem einheitlichen Beispiel.
Zu Beginn steht der Entwurf eines Star-Schemas.
(Damit soll nicht gesagt werden, dass ein Data Warehouse nur
aus einem Star-Schema besteht). Dieses Beispiel kann man durch
die mitgelieferten Sourcen bzw. abgedruckten Skripte auch in
einer eigenen Umgebung realisieren. Damit erhält man sofort
eine Übungsumgebung, um die Wirkungsweise der jeweiligen
Datenbank-Features zu testen.
Zu dem Starschema gehören auch passende Abfragen, die
möglichst viele potentiellen Problemstellungen bei der Abfrage
des Schemas abdecken. Die Abfragen sind einfach und damit
überschaubar gehalten. Die Beispielperformance-Werte liefern
eine erste Orientierung, welcher Optimierungserfolg bei den
jeweiligen Features erreichbar sein sollte. Die Werte stammen
nur von einem schlichten Desktop-Rechner (also keine
Hochleistungsmaschine). Das reicht, um die prinzielle
Vorgehensweise für Optimierungen aufzuzeigen. Aber bereits in
dieser Beispiel-Umgebung fällt es bei einigen Abfragen
schwer, Performance-Steigerungen durch einzelne Features
aufzuzeigen, da man sich auch bei einem Datenvolumen von mehr
als 50 Millionen Sätzen in Anwortzeitbereichen von weniger als
einer Sekunde bewegt. Und hier sind oftmals noch
Netzübertragungs- und Bildschirmaufbauzeiten enthalten.
Für das Starschema wird exemplarisch die passende (Bitmap-)
Indizierung und Partitionierung vorgestellt. Dann folgen die
nötigen Materialized Views. Die Summe aller Techniken führt in
dem ausgeführten Beispiel zu fast nicht mehr spürbaren
Antwortzeiten bei allen Beispielabfragen.
Um eine leichtere Orientierung zu geben, sind an einigen
Stellen farbige Blöcke eingebaut. Diese bedeuten:
Performance-Hinweise
Für diesen Punkt relevante Fragestellungen
Für diesen Punkt passende Dictionary-View
Da diese Sammlung nicht komplett und nicht fehlerfrei ist und
wahrscheilich ständig korrigiert und ergänzt werden muss,
bitten wir jeden, der damit arbeitet, um Feedback, Korrekturen
und Verbesserungsvorschläge (-> [email protected])
Die Beispieldaten zu dieser Skriptesammlung sind zu finden
unter.
http://www.oracledwh.de/downloads/AutoIndex2.2.4/index.php?dir=downloads/Kurs_Materialien_und_DWH_TIF_und
_Angebote/&file=Beispieldaten_Star_Skriptesammlung.zip
Eine Vorgehensweise für die Installation finden Sie am Ende
von dieser Skriptesammlung.
Document1
5 /41
Data Warehouse Technik im Fokus - Skripte in Kurzform
6 /41
Allgemeine Hilfen
Metadaten-DDL für Objekte aus dem Dictionary generieren lassen
Einrichten und Einstellen einer Testumgebung
select dbms_metadata.get_ddl('INDEX','IDX_BILDUNGSGRUPPE_BM')
FROM dual
SELECT
dbms_metadata.get_ddl('TABLE','BESTELLUNG_PART_RANGE_HASH')
FROM dual;
Hier wird davon ausgegangen, dass man mit SQL Plus arbeitet.
Alternativen sind z. B. der SQL Developer
Mess-Einstellungen + allgemeine Settings in SQLPlus
-- SET TIMING ON
-- SET AUTOTRACE ON / set autotrace traceonly
-- SET AUTOT[RACE] {OFF | ON | TRACE[ONLY]} [EXP[LAIN]]
[STAT[ISTICS]]
-- set pagesize 99
-- set heading off
-- set line 400
-- set long nnnn (vergößern des Ausgabe-Puffer)
Gelöschte Tabellen endgültig löschen
PURGE RECYCLEBIN
Oder gleich arbeiten mit [DROP TABLE tab_name PURGE;]
Ausschalten der Recyclebin-Funktion
alter session set recyclebin=off;
alter system flush shared_pool;
alter system flush BUFFER_CACHE;
alter system flush GLOBAL
SHOW PARAMETER …
oder die View V$PARAMETER abfragen.
select name,value, description from v$parameter;
SQL> desc v$parameter
Name
------------------------NUM
NAME
TYPE
VALUE
DISPLAY_VALUE
ISDEFAULT
ISSES_MODIFIABLE
ISSYS_MODIFIABLE
ISINSTANCE_MODIFIABLE
ISMODIFIED
ISADJUSTED
ISDEPRECATED
ISBASIC
DESCRIPTION
UPDATE_COMMENT
HASH
Dictionary-Views auslesen
column comments format a50
select * from dict where TABLE_NAME like 'V$SESSION%';
TABLE_NAME
COMMENTS
----------------------------------------------------------V$SESSION
Synonym for V_$SESSION
V$SESSION_BLOCKERS
Synonym for V_$SESSION_BLOCKERS
V$SESSION_CONNECT_INFO Synonym for V_$SESSION_CONNECT_INFO
V$SESSION_CURSOR_CACHE Synonym for V_$SESSION_CURSOR_CACHE
Ändern der Berücksichtigung Groß-/Kleinschreibweise bei Logon
alter system set sec_case_sensitive_logon=FALSE;
SQL Plus
user/passwort@ORACLE_SID -> geht über Listener
user/passwort -> ohne Listener
sys/passwort@ORACLE_SID as sysdba
sys/passwort as sysdba
“/ as sysdba”
-- listet alle SQLPLUS-Befehle auf
Weitere Hilfe mit
Help [commando]
Document1
SQL> help get
@@
APPEND
BREAK
CLEAR
CONNECT
DEL
EDIT
GET
INPUT
PAUSE
QUIT
REPFOOTER
RESERVED WORDS
(PL/SQL)
SET
SPOOL
STARTUP
TTITLE
WHENEVER OSERROR
emctl start dbconsole
Wenn es mal klemmt
Bei Fehlern wie:
The OracleDBConsole[ServiceName] service could not be started.
A service specific error occurred: 2
Hilft oft nur das Neukonfigurieren
-Linux
Dbstart
-Windows
set ORACLE_SID=orcl
set ORACLE_HOME=D:\ora
%oracle_home%\BIN\oradim -STARTUP -SID orcl -SYSPWD sys
Entweder
Beispiel
@
ACCEPT
ATTRIBUTE
CHANGE
COMPUTE
DEFINE
DISCONNECT
EXIT
HOST
PASSWORD
PROMPT
REMARK
RESERVED WORDS
(SQL)
SAVE
SHUTDOWN
START
TIMING
VARIABLE
XQUERY
Starten der Console
Starten der Datenbank
format a25
format a25
Systemparameter abfragen
Help Index
https://192.168.1.14:1158/em
https://hostname:1158/em
Datenbank, Listener und BS-Variablen
SELECT-Ausgabeformatierung
sqlplus
sqlplus
sqlplus
sqlplus
sqlplus
Aufruf im Browser z. B. mit
emca -deconfig dbcontrol db
emca -config dbcontrol db
Speicher leeren
column feld
column feld
Enterprise Manager
/
ARCHIVE LOG
BTITLE
COLUMN
COPY
DESCRIBE
EXECUTE
HELP
LIST
PRINT
RECOVER
REPHEADER
RUN
SHOW
SQLPLUS
STORE
UNDEFINE
WHENEVER SQLERROR
Listener starten und Status abfragen
Lsnrctl start
Lsnrctl status
Erreichbarkeit einer Datenbank über SID-Abfrage
Tnsping sid-name
Data Warehouse Technik im Fokus - Skripte in Kurzform
7 /41
Beispielumgebung
In diesewr Unterlage wird ein durchgägngiges Beispiel genutzt,
so dass immer wieder dieselben Tabellennamen und Struturen zu
finden sind.
Beispiel-OLTP Schema
Einfaches OLTP-Schema. Geeignet zur Diskussion der ERModellierung. Aus dieser Informations-Grundmenge lässt sich
das weiter unten dargestllte Star-Schema ableiten.
Vergleichs-Demo-Umgebung Steckbrief
Skript –Tabellen OLTP-System
CREATE TABLE BESTELLUNG (
BESTELLNR
KUNDENNR
ORTNR
BESTELLDATUM
NUMBER,
NUMBER,
NUMBER,
DATE);
CREATE TABLE kunde (
KUNDENNR
KUNDENNAME
BERUFSGRUPPE
SEGMENT
NUMBER(10) ,
VARCHAR2(20) ,
VARCHAR2(20) ,
NUMBER(10));
CREATE TABLE BESTELLPOSITION (
BESTELLNR
POSITIONSNR
MENGE
ARTIKELNR
number(4) ,
number(4) ,
NUMBER(4) ,
NUMBER(10));
CREATE TABLE ARTIKEL (
ARTIKEL_ID
ARTIKEL_NAME
GRUPPE_NR
NUMBER(3),
VARCHAR2(50),
NUMBER(3);
CREATE TABLE ARTIKEL_GRUPPEN (
GRUPPE_NR
GRUPPE_NAME
SPARTE_NR
NUMBER(3),
VARCHAR2(50),
NUMBER(3);
CREATE TABLE ARTIKEL_SPARTEN (
SPARTE_NR
SPARTE_NAME
NUMBER(3),
VARCHAR2(50);
Beispiel-Star Schema
Das folgende Star-Schema wird bei den anschließenden
Beispielabfragen verwendet.
Indizierung: Alle Dimensionstabellen (D-...) verfügen über
einen Unique-Index auf ihren Prmary-Key-Feldern. Die FaktenTabelle (F_UMSATZ) verfügt über jeweils einen Bitmap-Index auf
jedem Foreign-Key-Feld. Ein Foreign-Key-Constraint muss nicht
definiert sein.
Document1
(In dieser Unterlage werden Beispielabfragen und Abfragezeiten
angegeben, die in der hier beschriebenen Umgebung getestet
wurden. Die Daten können entsprechend der Anleitung am Ende
dieser Skriptesammlung geladen werden)
TABLE_NAME
BLOCKS
GB
NUM_ROWS PCT_FREE
------------------------- ------- ---------- -------D_ARTIKEL
5 .00004
129
10
D_KUNDE
28 .000224
1029
10
D_REGION
73 .000584
7202
10
D_ZEIT
43 .000344
5844
10
D_VERTRIEBSKANAL
5 .00004
7
10
F_UMSATZ
276890 2.21512
51200000
10
Eigenschaft des Demosystems
Compression
Bitmap auf Fakten-FK-Felder
Unique Key PK-Felder der Dimensionen
Partitioning
Results Cache
Null-Werte
Server-CPU-Kerne
Server-RAM
Server-BS
Oracle-DB
Storage
Durchsatz
Nein(Ja)
Ja
Ja
Nein(Ja)
Nein
Keine
4
16 GB
Linux OEL 6
11.2.0.3 (EE)
Direkt
~180 MB/sec
Skript Fakten-Tabelle
CREATE TABLE F_UMSATZ(
ARTIKEL_ID
KUNDEN_ID
ZEIT_ID
REGION_ID
KANAL_ID
UMSATZ
MENGE
UMSATZ_GESAMT
);
NUMBER(10),
NUMBER(10),
DATE,
NUMBER(10),
NUMBER(10),
NUMBER(10),
NUMBER(10),
NUMBER(10)
Skript Kunden-Dimension
CREATE TABLE
KUNDENNR
GESCHLECHT
VORNAME
NACHNAME
TITEL
ANREDE
GEBDAT
BRANCHE
WOHNART
KUNDENART
BILDUNG
ANZ_KINDER
EINKOMMENSGRUPPE
ORTNR
BERUFSGRUPPE
STATUS
STRASSE
TELEFON
TELEFAX
KONTAKTPERSON
FIRMENRABATT
BERUFSGRUPPEN_NR
BILDUNGS_NR
EINKOMMENS_NR
WOHNART_NR
HAUSNUMMER
PLZ
ORT
KUNDENKARTE
ZAHLUNGSZIEL_TAGE
KUNDEN_ID
D_KUNDE (
NUMBER,
VARCHAR2(10),
VARCHAR2(50),
VARCHAR2(50),
VARCHAR2(20),
VARCHAR2(10),
DATE,
VARCHAR2(30),
VARCHAR2(30),
NUMBER,
VARCHAR2(30),
VARCHAR2(5),
VARCHAR2(30),
NUMBER,
VARCHAR2(30),
VARCHAR2(1),
VARCHAR2(100),
VARCHAR2(30),
VARCHAR2(30),
NUMBER,
VARCHAR2(10),
VARCHAR2(1),
VARCHAR2(1),
VARCHAR2(1),
VARCHAR2(1),
NUMBER(10,0),
VARCHAR2(10),
VARCHAR2(100),
NUMBER,
VARCHAR2(4000),
NUMBER
Data Warehouse Technik im Fokus - Skripte in Kurzform
TOTAL
TOTAL_NR
VARCHAR2(20),
NUMBER);
Skript Artikel-Dimension
CREATE TABLE D_ARTIKEL
( ARTIKEL_NAME
ARTIKEL_ID
GRUPPE_NR
GRUPPE_NAME
SPARTE_NAME
SPARTE_NR
) ;
VARCHAR2(50),
NUMBER(3,0),
NUMBER(3,0),
VARCHAR2(50),
VARCHAR2(50),
NUMBER(3,0),
Skript Regionen-Dimension
CREATE TABLE D_REGION
ORTNR
ORT
KREISNR
KREIS
LAND
LANDNR
REGION
REGIONNR
REGION_ID
) ;
(
NUMBER(8,0),
VARCHAR2(50),
NUMBER(8,0),
VARCHAR2(50),
VARCHAR2(50),
NUMBER(8,0),
VARCHAR2(50),
NUMBER(8,0),
NUMBER(22,0)
Skript Zeit-Dimension
CREATE TABLE D_ZEIT
ZEIT_ID
DATUM_ID
TAG_DES_MONATS
TAG_DES_JAHRES
WOCHE_DES_JAHRES
MONATS_NUMMER
MONAT_DESC
QUARTALS_NUMMER
JAHR_NUMMER
) ;
DATE ,
NUMBER(4),
NUMBER(2,0),
NUMBER(3,0) ,
NUMBER(2,0) ,
NUMBER(2,0) ,
VARCHAR2(9) ,
NUMBER(1,0) ,
NUMBER(4,0)
CREATE TABLE D_VERTRIEBSKANAL
(KANAL_ID
NUMBER,
VERTRIEBSKANAL
VARCHAR2(20 BYTE),
KANALBESCHREIBUNG
VARCHAR2(20 BYTE),
VERANTWORTLICH
VARCHAR2(20 BYTE),
KLASSE
NUMBER
) ;
Skript Unique Keys für die Dimensionstabellen [nicht nötig]
"D_KUNDE_PK" ON "D_KUNDE" ("KUNDEN_ID");
"D_ARTIKEL_PK" ON "D_ARTIKEL"
"D_REGION_PK" ON "D_REGION" ("REGION_ID");
"D_ZEIT_PK" ON "D_ZEIT" ("ZEIT_ID");
"D_KANAL_PK" ON "D_VERTRIEBSKANAL"
Skript Bitmap-Indexe auf FK-Felderder Fakten-Tabelle F_UMSATZ
CREATE
CREATE
CREATE
CREATE
CREATE
bitmap
bitmap
bitmap
bitmap
bitmap
index
index
index
index
index
idx_ARTIKEL_ID_BM on F_UMSATZ(ARTIKEL_ID);
idx_ZEIT_ID_BM on F_UMSATZ(ZEIT_ID);
idx_KUNDEN_ID_BM on F_UMSATZ(KUNDEN_ID);
idx_REGION_ID_BM on F_UMSATZ(REGION_ID);
idx_KANAL_ID_BM on F_UMSATZ(KANAL_ID);
Skript Drop Bitmap Indexe
DROP
DROP
DROP
DROP
DROP
INDEX
INDEX
INDEX
INDEX
INDEX
idx_ARTIKEL_ID_BM;
idx_ZEIT_ID_BM;
idx_KUNDEN_ID_BM;
idx_REGION_ID_BM;
idx_KANAL_ID_BM;
Skript Primary-Key-Felder auf Dimensions-Tabellen [nicht nötig]
ALTER TABLE D_Region ADD CONSTRAINT pk_Region PRIMARY KEY
(Region_id);
ALTER TABLE D_Zeit ADD CONSTRAINT pk_Zeit PRIMARY KEY
(Zeit_id);
ALTER TABLE D_Artikel ADD CONSTRAINT pk_Artikel PRIMARY KEY
(artikel_id);
ALTER TABLE D_Kunde ADD CONSTRAINT pk_Kunde PRIMARY KEY
(kunden_id);
ALTER TABLE D_VERTRIEBSKANAL ADD CONSTRAINT pk_VERTRIEBSKANAL
PRIMARY KEY (KANAL_ID);
Skript Dimensional Table D_ARTIKEL
DROP DIMENSION D_ARTIKEL;
CREATE DIMENSION d_artikel
LEVEL artikel IS d_artikel.artikel_id
LEVEL gruppe IS d_artikel.gruppe_nr
LEVEL sparte IS d_artikel.sparte_nr
HIERARCHY h_art (
artikel CHILD OF
gruppe CHILD OF
sparte)
ATTRIBUTE artikel DETERMINES (d_artikel.artikel_name)
ATTRIBUTE gruppe DETERMINES (d_artikel.gruppe_name)
ATTRIBUTE sparte DETERMINES (d_artikel.sparte_name);
Skript Dimensional Table D_Region
DROP DIMENSION D_REGION;
CREATE DIMENSION D_REGION
LEVEL ort
IS d_region.REGION_id
LEVEL kreis
IS d_region.kreisnr
LEVEL land
IS d_region.landnr
LEVEL region
IS d_region.regionnr
Document1
HIERARCHY
Ort
Kreis
Land
Region
ATTRIBUTE
ATTRIBUTE
ATTRIBUTE
ATTRIBUTE
h_region (
CHILD OF
CHILD OF
CHILD OF
)
Ort
DETERMINES
Kreis DETERMINES
Land
DETERMINES
Region DETERMINES
(d_region.ort, d_region.ortnr)
(d_region.kreis)
(d_region.land)
(d_region.region);
Skript Dimensional Table D_Zeit
DROP DIMENSION D_Zeit;
CREATE DIMENSION D_Zeit
LEVEL Tag
IS D_Zeit.Zeit_id
LEVEL Monat
IS D_Zeit.Monats_nummer
LEVEL Quartal
IS D_Zeit.Quartals_Nummer
LEVEL Jahr
IS D_Zeit.Jahr_Nummer
HIERARCHY h_region (
Tag
CHILD OF
Monat CHILD OF
Quartal
CHILD OF
Jahr )
ATTRIBUTE Tag
DETERMINES (D_Zeit.Datum_ID,
D_Zeit.Tag_des_Monats, D_Zeit.Tag_des_Jahres,
D_Zeit.Woche_Des_Jahres)
ATTRIBUTE Monat DETERMINES (D_Zeit.Monat_Desc)
(
Skript Vertriebskanal-Dimension
CREATE UNIQUE INDEX
CREATE UNIQUE INDEX
("ARTIKEL_ID");
CREATE UNIQUE INDEX
CREATE UNIQUE INDEX
CREATE UNIQUE INDEX
("KANAL_ID");
8 /41
Skript Dimensional Table D_Kunde
DROP DIMENSION D_Kunde;
CREATE DIMENSION D_Kunde
LEVEL Kunde
IS D_Kunde.Kunden_id
LEVEL Beruf
IS D_Kunde.Berufsgruppen_nr
LEVEL Einkommen
IS D_Kunde.Einkommens_nr
LEVEL Wohnart
IS D_Kunde.Wohnart_nr
LEVEL Bildung
IS D_Kunde.Bildungs_nr
LEVEL Ort
IS D_Kunde.Ortnr
HIERARCHY h_Beruf (Kunde CHILD OF Beruf)
HIERARCHY h_Einkommen (Kunde CHILD OF Einkommen)
HIERARCHY h_Wohnart (Kunde CHILD OF Wohnart)
HIERARCHY h_Bildung (Kunde CHILD OF Bildung)
HIERARCHY h_Ort
(Kunde CHILD OF Ort)
ATTRIBUTE Kunde
DETERMINES
(D_Kunde.KUNDENNR,
D_Kunde.Geschlecht ,
D_Kunde.Vorname ,
D_Kunde.Nachname ,
D_Kunde.Titel ,
D_Kunde.Anrede,
D_Kunde.Gebdat,
D_Kunde.Branche,
D_Kunde.Kundenart ,
D_Kunde. Anz_kinder,
D_Kunde.Status,
D_Kunde.Strasse,
D_Kunde.Telefon ,
D_Kunde.Telefax ,
D_Kunde.Kontaktperson,
D_Kunde.Firmenrabatt,
D_Kunde.Hausnummer,
D_Kunde.Kundenkarte ,
D_Kunde.Zahlungsziel_tage,
D_Kunde.Total,
D_Kunde.Total_NR)
ATTRIBUTE Beruf DETERMINES (D_Kunde.Berufsgruppe)
ATTRIBUTE Einkommen DETERMINES (D_Kunde.Einkommensgruppe)
ATTRIBUTE Wohnart DETERMINES (D_Kunde.Wohnart)
ATTRIBUTE Bildung DETERMINES (D_Kunde.Bildung)
ATTRIBUTE Ort DETERMINES (D_Kunde.Ort, D_Kunde.PLZ)
Data Warehouse Technik im Fokus - Skripte in Kurzform
Beispielabfragen auf das Beispiel-Star Schema
Beispielabfrage 1a Generische Abfrage auf vorgenanntes Star-Schema
SELECT a.sparte_name, z.Jahr_Nummer, r.land,v.vertriebskanal,
sum(U.umsatz), sum(U.menge)
FROM
f_Umsatz U,
d_region r,
d_zeit z,
D_artikel a,
D_Vertriebskanal V
WHERE
U.zeit_id
= z.zeit_id
AND U.REGION_ID
= R.REGION_ID
AND U.artikel_id
= a.artikel_id
AND U.Kanal_ID
= V.Kanal_ID
GROUP by a.sparte_name, z.Jahr_Nummer, r.land,
v.vertriebskanal ;
Parallel
Sekunden
P0
39,1
P2
22,5
P4
13,4
P8
16,8
P16
20
Beispielabfrage 1b Einfache Abfrage Summe Umsatz an einem Tag

SELECT /*+ no cache */ sum(UMSATZ) Umsatz
FROM F_UMSATZ
WHERE
zeit_ID = to_date('10.03.2011','DD.MM.YYYY')
UMSATZ
---------13883392
Parallel
P0
Sekunden
2,6
Beispielabfrage 1c Summe Umsatz an einem Tag und Vertriebskanal
SELECT /*+ no cache */ sum(UMSATZ) Umsatz
FROM F_UMSATZ U, D_vertriebskanal V
WHERE
u.kanal_id = v.kanal_id
and zeit_ID = to_date('10.03.2011','DD.MM.YYYY')
and V.vertriebskanal = 'Shop';
Parallel
P0
Sekunden
2,5
Beispielabfrage 2 Einschränkungen über alle Dimensionen
SELECT sum(u.UMSATZ) Umsatz,
R.REGION,
Z.Quartals_nummer Quartal
FROM
F_UMSATZ U,
D_Artikel A,
D_Region R,
D_Zeit Z,
D_Kunde K,
D_Vertriebskanal V
WHERE
U.Kunden_ID
= K.Kunden_ID
AND U.Zeit_ID
= Z.Zeit_ID
AND U.REGION_ID
= R.Region_ID
AND U.Artikel_ID
= A.Artikel_ID
AND U.Kanal_ID
= V.Kanal_ID
AND Z.JAHR_NUMMER
= 2011
AND A.GRUPPE_NAME
= 'Bad_Sanitaer'
AND K.BERUFSGRUPPE
= 'Arbeiter'
AND R.REGION
IN
('Mitte','Sued','Nord')
AND V.Vertriebskanal
= 'Shop'
Group by R.Region,Z.Quartals_nummer
Order by Z.Quartals_nummer;
Parallel
Sekunden
P0
2,6
P2
2,6
P4
4,2
P8
4,6
P16
4,2
Beispielabfrage3 (Ein-/Ausschalten Where-Argumente /Test Star Query
SELECT a.sparte_name, z.Jahr_Nummer, r.land, sum(U.umsatz),
sum(U.menge)
FROM
f_Umsatz U,
d_region r,
d_zeit z,
D_artikel a
WHERE
U.zeit_id
= z.zeit_id
AND
U.REGION_ID
= R.REGION_ID
AND
U.artikel_id
= a.artikel_id
and
z.jahr_nummer
= 2010
and
R.Land = 'Bayern'
GROUP by
a.sparte_name, z.Jahr_Nummer, r.land;
Document1
9 /41
Parallel
P0
P2
P4
P8
P16
Sekunden
11,3
6,4
3,2
5,8
5,3
Beispielabfrage 4: Top 3 Länder bezogen auf Einzelverkäufe
select * from
( select count(*) Anzahl_Verkaeufe, r.land Bundesland
from f_umsatz u, d_region r
WHERE
U.REGION_ID
= R.REGION_ID
group by r.land
order by anzahl_verkaeufe desc )
where rownum < 4;
[count(*) wegen der leichteren Rewrit-Fähigkeit]
BUNDESLAND
ANZAHL
------------------------------ ---------Rheinland Pfalz
13674496
Bayern
13261312
Schleswig Holstein
8107008
Parallel
P0
P2
P4
P8
P16
Sekunden
12
10,5
3,7
3,8
4,1
Beispielabfrage 5: Umsatz nach Quartalen
select sum(u.umsatz)
Umsatz,
z.Jahr_nummer
Jahr,
z.Quartals_nummer
Quartal
from
f_umsatz u,
d_zeit z
where
z.zeit_id = u.zeit_id and
z.Jahr_nummer between 2006 and 2011
group by z.Jahr_nummer,z.Quartals_nummer
order by z.Jahr_nummer,z.Quartals_nummer
UMSATZ
JAHR
QUARTAL
---------- ---------- ---------1579442176
2006
1
1558222336
2006
2
1522254336
2006
3
1646631936
2006
4
1533571072
2007
1
1580020224
2007
2
~~~
Parallel
P0
P2
P4
P8
P16
Sekunden
10,1
7,1
2,6
4,7
2,5
Beispielabfrage 6: Nach Umsatzstärke sortierte Quartals-Rangfolge
select sum(u.umsatz) Umsatz,
z.Jahr_nummer Jahr
,z.Quartals_nummer Quartal,
RANK() OVER (PARTITION by z.Jahr_nummer ORDER
sum(U.umsatz) ASC ) AS Rangfolge
from
f_umsatz u,
d_zeit z
where
z.zeit_id = u.zeit_id and
z.Jahr_nummer between 2006 and 2011
group by z.Jahr_nummer,z.Quartals_nummer
order by z.Jahr_nummer,Rangfolge;
UMSATZ
JAHR
QUARTAL RANGFOLGE
---------- ---------- ---------- ---------1522254336
2006
3
1
1558222336
2006
2
2
1579442176
2006
1
3
1646631936
2006
4
4
1533571072
2007
1
1
1563792384
2007
3
2
1566097920
2007
4
3
1580020224
2007
2
4
1521408512
2008
2
1
1551963136
2008
1
2
1610153472
2008
3
3
~~~
Parallel
P0
P2
P4
P8
P16
Sekunden
9,0
5,1
2,6
2,7
2,8
Beispielabfrage 7:: Das umsatzstärkste Quartal pro Jahr
select * from
BY
Data Warehouse Technik im Fokus - Skripte in Kurzform
(select sum(u.umsatz) Umsatz,
z.Jahr_nummer Jahr
,z.Quartals_nummer "Top-Quartal",
RANK() OVER (PARTITION by z.Jahr_nummer ORDER
sum(U.umsatz) ASC ) AS Rangfolge
from
f_umsatz u,
d_zeit z
where
z.zeit_id = u.zeit_id and
z.Jahr_nummer between 2006 and 2011
group by z.Jahr_nummer,z.Quartals_nummer)
where Rangfolge = 1
order by Jahr;
Innenkabel 3 Adern 2
BY
UMSATZ
JAHR Top-Quartal RANGFOLGE
---------- ---------- ----------- ---------1522254336
2006
3
1
1533571072
2007
1
1
1521408512
2008
2
1
1488578048
2009
1
1
1467155968
2010
4
1
1528411648
2011
1
1
Parallel
P0
P2
P4
P8
P16
Sekunden
9,6
5,1
2,2
2,8
1,8
Beispielabfrage 8: Stärkster Umsatzmonat pro Bundesland
SELECT
FROM
*
(SELECT
land Bundesland,
monat_desc Monat,
jahr_nummer Jahr,
sum(umsatz) as Umsatz,
RANK() OVER(PARTITION BY r.land ORDER BY
sum(u.umsatz) DESC) AS rangfolge
FROM
d_zeit z,
d_region r,
f_umsatz u
WHERE
z.zeit_id = u.zeit_id
AND r.region_id = u.region_id
AND z.jahr_nummer = '2010'
GROUP BY r.land, z.monat_desc, jahr_nummer
ORDER BY jahr_nummer
)
WHERE
rangfolge < 2
order by Bundesland;
BUNDESLAND
-------------------Baden Wuerttemberg
Bayern
Berlin
Bremen
Hamburg
Hessen
Niedersachsen
Nordrhein Westfalen
Rheinland Pfalz
Saarland
Schleswig Holstein
Parallel
P0
P2
P4
P8
P16
MONAT
JAHR
UMSATZ RANGFOLGE
-------------- ---------- ---------October
2010
59450368
1
July
2010 163219968
1
December 2010
807424
1
June
2010
75264
1
June
2010
1023488
1
November 2010
36823040
1
December 2010
85943808
1
February 2010
26347520
1
January
2010 157769728
1
August
2010
5460992
1
May
2010
87066624
1
Sekunden
6,2
2,8
3,4
1,6
1,7
Beispielabfrage9: Top 10 Artikel bezogen auf Menge / Rank /Subquery
SELECT *
FROM
(SELECT
Artikel_Name as Artikel, sum(U.menge) AS Gesamtmenge,
RANK() OVER (ORDER BY sum(U.menge) DESC ) AS
Rangfolge
from F_umsatz U, D_Artikel A
WHERE
U.artikel_id = a.artikel_id group by a.artikel_name)
WHERE rownum < 11;
ARTIKEL
GESAMTMENGE RANGFOLGE
----------------------------- ----------- ---------Wasserhahn
23144960
1
Muffe 18mm
22593536
2
Aussenkabel 4 Adern 2
22431744
3
Luesterklemmen 2
22123008
4
Topf_Guss_Klein
21908480
5
Schubkarre
21797888
6
Gluebirne Halogen 200 Watt
21556224
7
Aussenkabel 3 Adern 1,5
21442048
8
Aussenkabel 5 Adern 2
21420032
9
Document1
10 /41
21405184
Parallel
P0
P2
P4
P8
P16
10
Sekunden
16,8
8,5
4,3
4,4
4,3
Beispielabfrage9a: Top 10 Artikel bezogen auf Menge / Rank /Subquery
SELECT *
FROM
(SELECT
Gruppe_Name , sum(U.menge) AS Gesamtmenge,
RANK() OVER (ORDER BY sum(U.menge) DESC ) AS
Rangfolge
from F_umsatz U, D_Artikel A
WHERE
U.artikel_id = a.artikel_id group by a.gruppe_name)
Beispielabfrage10: -- Top 10 Artikel bezogen auf Umsatz in einem Jahr
SELECT * FROM
(SELECT
a.Artikel_Name as Artikel,
r.Land Bundesland,
z.Jahr_nummer Jahr,
sum(U.umsatz) AS Wert,
sum(U.Menge) Menge,
round(sum(U.umsatz) / sum(U.Menge),2) Ums_pro_Art,
RANK() OVER (ORDER BY sum(U.umsatz) DESC ) AS
Rangfolge
from F_umsatz U, D_Artikel A ,D_Zeit z, d_region r
WHERE
U.artikel_id =
a.artikel_id
and
U.REGION_ID =
R.REGION_ID
AND
U.zeit_id
= z.zeit_id
AND
z.jahr_nummer
= 2010
group by a.artikel_name,r.Land,z.Jahr_nummer)
WHERE rownum < 11;
ARTIKEL
BUNDESLAND
JAHR
WERT
MENGE UMS._PRO_ART. RANGFO.
------------------------ ---------------------- -------- ------- ------------ ----
Wandspiegel 40x60
Handtuchhalter
Wandspiegel 50x80
Fahrradhalter
Bindeseil
Gluebirne Kerze 40 Watt
Zusatzlicht_Front
Innenkabel 3 Adern 1,5
Aussenkabel 5 Adern 1,5
Holzschauben_2Kg
Rheinland
Bayern
Rheinland
Rheinland
Bayern
Rheinland
Bayern
Bayern
Bayern
Rheinland
Parallel
P0
P2
P4
P8
P16
Pfalz 2010
2010
Pfalz 2010
Pfalz 2010
2010
Pfalz 2010
2010
2010
2010
Pfalz 2010
25700352
25004544
24927744
24101376
23774208
23672832
22036480
21995520
21216768
21105152
570368
756736
534016
713216
559104
470016
500224
480768
419840
573952
45.05 1
33.04 2
46.67 3
33.75 4
42.52 5
50.36 6
44.05 7
45.75 8
50.53 9
36.77 10
Sekunden
9,8
3,3
1,7
1,9
1,8
Beispielabfrage 11: - Top 3 Produkte je Produktgruppe sortiert nach
Rangfolge
SELECT
FROM
*
(SELECT artikel_name Artikel, gruppe_name Prod_Grp,
sum(U.Umsatz) AS Umsatz,
RANK() OVER (PARTITION by a.gruppe_name ORDER BY
sum(U.umsatz) DESC ) AS Rangfolge
FROM f_umsatz U, d_artikel A
WHERE U.artikel_id
= a.artikel_id
GROUP by a.gruppe_name,a.artikel_name
ORDER by a.gruppe_name)
WHERE Rangfolge < 4;
ARTIKEL
-----------------------Wasserhahn
Wandspiegel 50x60
Waschbecken 50x80
Elektrohobel
Schleifmaschine 600 Watt
Bohrmaschine 600 Watt
Aussenkabel 4 Adern 2
Gluebirne Kerze 25 Watt
Luesterklemmen 2
Hacke_5Kg
Schubkarre
Wasservorratsbehaelter
PROD_GRP
UMSATZ RANGFOLGE
------------------ ---------- -Bad_Sanitaer
881696768 1
Bad_Sanitaer
853362688 2
Bad_Sanitaer
837804032 3
Elektro-Werkzeuge
813489152 1
Elektro-Werkzeuge
793825792 2
Elektro-Werkzeuge
782154752 3
Elektroartikel
880760320 1
Elektroartikel
858101760 2
Elektroartikel
848047616 3
Gartenbedarf
888975872 1
Gartenbedarf
856668160 2
Gartenbedarf
844909056 3
~~~
Parallel
P0
P2
P4
P8
P16
Sekunden
19
10,2
5,3
6,9
8,2
Beispielabfrage 12: Die Top-Produktgruppe pro Bundesland
SELECT * FROM
(SELECT
R.Land Bundesland,
gruppe_name Prod_Grp,
sum(U.Umsatz) AS Umsatz,
Data Warehouse Technik im Fokus - Skripte in Kurzform
Rank() OVER (PARTITION by R.Land ORDER
sum(U.umsatz) DESC ) AS Rangfolge
FROM f_umsatz U, d_artikel A , d_region R
WHERE
U.artikel_id
= a.artikel_id
and U.Region_ID
= r.Region_ID
GROUP by R.Land, gruppe_name
order by R.land)
where Rangfolge = 1
;
LAND
-------------------Baden Wuerttemberg
Bayern
Berlin
Bremen
Hamburg
Hessen
Niedersachsen
Nordrhein Westfalen
Rheinland Pfalz
Saarland
Schleswig Holstein
Parallel
P0
P2
P4
P8
P16
BY
PROD_GRP
UMSATZ RANGFOLGE
--------------- ---------- --Bad_Sanitaer
2517655040
1
Bad_Sanitaer
6928505856
1
KFZ-Zubehoer
5216256
1
Haushaltswaren
7249920
1
Elektroartikel
11321344
1
Bad_Sanitaer
1473691648
1
Bad_Sanitaer
3481312768
1
Bad_Sanitaer
1065768960
1
Bad_Sanitaer
7339374592
1
Bad_Sanitaer
97358848
1
Bad_Sanitaer
4261867520
1
Sekunden
25,3
12,2
6,3
6,7
7,2
SELECT *
FROM
(SELECT gruppe_name Prod_grp, land Bundesland, sum(menge)
as Umsatz,
max(sum(menge)) over (partition by
gruppe_name) as Max_Ums_Land
FROM D_region R, d_artikel a, f_umsatz U
WHERE
R.region_id = U.region_id AND
a.artikel_id = U.artikel_id
GROUP by gruppe_name, land
ORDER by gruppe_name , land )
WHERE Umsatz = Max_Ums_Land;
BUNDESLAND
UMSATZ MAX_UMS_LAND
-------------------------- -----------Rheinland Pfalz 183886336
183886336
Rheinland Pfalz
34775552
34775552
Rheinland Pfalz 123813376
123813376
Rheinland Pfalz
87101952
87101952
Rheinland Pfalz
92366336
92366336
Rheinland Pfalz
85024256
85024256
Bayern
83915776
83915776
Sekunden
33.1
13.0
6,5
6,8
8,7
Beispielabfrage 14: Die Top und Flop Produktgruppe pro Bundesland
SELECT * FROM
(SELECT
R.Land Bundesland,
gruppe_name Prod_Grp,
sum(U.Umsatz) AS Umsatz,
Rank() OVER (PARTITION by R.Land ORDER
sum(U.umsatz) DESC ) AS Rangfolge
FROM f_umsatz U, d_artikel A , d_region R
WHERE
U.artikel_id
= a.artikel_id
and U.Region_ID
= r.Region_ID
GROUP by R.Land, gruppe_name
order by R.land)
where Rangfolge in (1,7);
BUNDESLAND
------------------Baden Wuerttemberg
Baden Wuerttemberg
Bayern
Bayern
Berlin
Berlin
Bremen
BY
PROD_GRP
UMSATZ RANGFOLGE
-------------------- ---------- ----Bad_Sanitaer
2517655040
1
Elektro-Werkzeuge
452903936
7
Bad_Sanitaer
6928505856
1
Elektro-Werkzeuge
1380406784
7
KFZ-Zubehoer
5216256
1
Heimwerker
2012160
7
Haushaltswaren
7249920
1
~~~
Parallel
P0
P2
P4
P8
P16
Sekunden
24,5
12.8
6,2
9,6
6,2
Beispielabfrage 15: Die Top 2 Produktgruppen pro Bundesland
SELECT * FROM
(SELECT r.land Bundesland, a.gruppe_name Prod_Grp,
sum(U.Umsatz) AS Top_Umsatz,
RANK() OVER (PARTITION by r.land ORDER BY
sum(U.umsatz) DESC ) AS Top_folge
FROM f_umsatz U, d_artikel A , d_region r
Document1
WHERE
U.artikel_id
= a.artikel_id
U.region_id
=r.region_id
GROUP by r.land,a.gruppe_name
ORDER by r.land)
WHERE Top_folge < 3;
Beispielabfrage 13: Land mit dem stärksten Umsatz je Produktgruppe
PROD_GRP
-----------------Bad_Sanitaer
Elektro-Werkzeuge
Elektroartikel
Gartenbedarf
Haushaltswaren
Heimwerker
KFZ-Zubehoer
Parallel
P0
P2
P4
P8
P16
11 /41
LAND
-------------------Baden Wuerttemberg
Baden Wuerttemberg
Bayern
Bayern
Berlin
Berlin
Bremen
Bremen
Hamburg
PROD_GRP
---------------Bad_Sanitaer
Elektroartikel
Bad_Sanitaer
Elektroartikel
KFZ-Zubehoer
Bad_Sanitaer
Haushaltswaren
Gartenbedarf
Elektroartikel
and
TOP_UMSATZ TOP_FOLGE
---------- --2517655040
1
1634190848
2
6928505856
1
4916009472
2
5216256
1
5194240
2
7249920
1
7211008
2
11321344
1
~~~
Parallel
P0
P2
P4
P8
P16
Sekunden
24,8
13,4
6,6
8,9
9,1
Beispielabfrage 16: Top/Bottom 2 Produktgruppen pro Bundesland
select Top.Bundesland,
top.Prod_grp,Top.top_umsatz,top.Top_folge,
Bottom.Prod_grp,bottom.Bottom_Umsatz, bottom.Bottom_folge From
(SELECT * FROM
(SELECT r.land Bundesland, a.gruppe_name Prod_Grp,
sum(U.Umsatz) AS Top_Umsatz,
RANK() OVER (PARTITION by r.land ORDER BY
sum(U.umsatz) DESC ) AS Top_folge
FROM f_umsatz U, d_artikel A , d_region r
WHERE
U.artikel_id
= a.artikel_id and
U.region_id
=r.region_id
GROUP by r.land,a.gruppe_name
ORDER by r.land)
WHERE Top_folge < 3) Top,
(SELECT * FROM
(SELECT r.land Bundesland, a.gruppe_name Prod_Grp,
sum(U.Umsatz) AS Bottom_Umsatz,
RANK() OVER (PARTITION by r.land ORDER BY
sum(U.umsatz) ASC ) AS Bottom_folge
FROM f_umsatz U, d_artikel A , d_region r
WHERE
U.artikel_id
= a.artikel_id and
U.region_id
=r.region_id
GROUP by r.land,a.gruppe_name
ORDER by r.land)
WHERE Bottom_folge < 3) Bottom
where top.Bundesland = bottom.Bundesland and
top.Top_folge = bottom.Bottom_folge
order by Top.Bundesland;
BUNDESLAND
PROD_GRP
TOP
UMSATZ
TOP
Folge
PROD_GRP
BOTTOM BOTTOM
UMSATZ FOLGE
--------------------- ---------------- ---------- -- -------------------------------- ---
Baden Wuerttemberg
Baden Wuerttemberg
Bayern
Bayern
Berlin
Berlin
Bremen
Bremen
Hamburg
Hamburg
Bad_Sanitaer
Elektroartikel
Bad_Sanitaer
Elektroartikel
Bad_Sanitaer
KFZ-Zubehoer
Haushaltswaren
Gartenbedarf
Heimwerker
Elektroartikel
2517655040
1634190848
6928505856
4916009472
5194240
5216256
7249920
7211008
7856640
11321344
1
2
1
2
2
1
1
2
2
1
Elektro-Werkzeuge
Heimwerker
Elektro-Werkzeuge
Heimwerker
Elektroartikel
Heimwerker
Bad_Sanitaer
Elektro-Werkzeuge
Gartenbedarf
Bad_Sanitaer
452903936
1180500480
1380406784
3230448640
3089408
2012160
1293824
1307136
1458688
1054720
1
2
1
2
2
1
1
2
2
1
~~~
Parallel
P0
P2
P4
P8
P16
Sekunden
50,1
25,8
13,1
16,9
14,4
Beispielabfrage 17: Über Quartale kumulierte Umsätze pro Kunde
SELECT k.nachName, z.jahr_nummer, z.quartals_nummer,
sum(u.menge) as Umsatz,
sum(sum(u.menge))
over (Partition By k.nachName
ORDER BY k.nachName, z.jahr_nummer, z.quartals_nummer
ROWS UNBOUNDED PRECEDING) as Umsatz_Summe
FROM d_kunde K, f_Umsatz U, d_zeit Z
WHERE
k.kunden_id = u.kunden_id
AND
to_char(Z.zeit_id) = to_char(u.zeit_id)
GROUP by K.NachName, z.jahr_nummer, z.quartals_nummer;
Parallel
Sekunden
P0
75,2
P2
31,7
P4
15,3
P8
23,7
P16
13,8
Beispielabfrage 18: Über Quartale kumulierte Umsätze pro Kunde (Jahr +
Kreis)
SELECT
k.nachName,r.kreis,
z.jahr_nummer,
Data Warehouse Technik im Fokus - Skripte in Kurzform
z.quartals_nummer,
sum(u.Umsatz) as Umsatz,
sum(sum(u.Umsatz)) over (Partition By k.nachName
ORDER BY k.nachName, z.jahr_nummer, z.quartals_nummer
ROWS UNBOUNDED PRECEDING) as Umsatz_Summe
FROM d_kunde K, f_Umsatz U, d_zeit Z, d_region r
WHERE
k.kunden_id = u.kunden_id
AND
U.zeit_id
= z.zeit_id
AND
R.region_id = U.region_id
AND
z.Jahr_nummer = 2010
and
r.kreisnr in (151,51,170,566)
GROUP by K.NachName,r.kreis, z.jahr_nummer, z.quartals_nummer;
Parallel
P0
P2
P4
P8
P16
Sekunden
2,1
1,6
1,2
1,5
1,2
Beispielabfrage 19: Wieviel Prozent des Gesamtumsatzes pro Land
machen die 3 Top Produkte aus
select a.land,
round(a.top_3_umsatz/1000000,2) Top_3_In_Mill,
round(b.Gesamt_pro_land/1000000,2)
Gesamt_pro_Land_in_Mill,
round(a.top_3_umsatz/b.Gesamt_pro_land*100,2)
Anteil_Prozent
from
(SELECT land, sum(umsatz) Top_3_Umsatz
FROM
(SELECT r.land, artikel_name Artikel, sum(U.Umsatz)
AS Umsatz,
RANK() OVER (PARTITION by r.land ORDER BY
sum(U.umsatz) DESC ) AS Rangfolge
FROM f_umsatz U, d_artikel A, d_region r
WHERE U.artikel_id
= a.artikel_id and
U.region_id = r.region_id
GROUP by r.land, a.artikel_name
ORDER by r.land)
WHERE Rangfolge < 4
group by land) a,
(SELECT land, sum(umsatz) Gesamt_pro_Land
from
f_umsatz U, d_region r
where
U.region_id = r.region_id
group by land) b
where
a.land = b.land;
LAND
TOP_3_IN_MILL GESAMT_PRO_LAND_IN_MILL ANTEIL_PROZENT
------------------- ------------- ----------------------- -------------Hamburg
11.45
39.26
29.18
Niedersachsen
362.68
12827.92
2.83
Schleswig Holstein
491.98
16262.01
3.03
Nordrhein Westfalen
152.71
4155.6
3.67
Berlin
5.68
28.19
20.13
Bremen
5.53
28.58
19.35
Baden Wuerttemberg
280.01
9413.63
2.97
Rheinland Pfalz
800.82
27477.07
2.91
Saarland
26.04
389.81
6.68
Bayern
739.02
26510.6
2.79
Hessen
180.83
5314.5
3.4
Parallel
P0
P2
P4
P8
P16
Sekunden
38,2
19,0
9,8
19,1
11,4
Beispielabfrage 20: ¼ der Kunden tragen zu ? % des Umsatzes bei?
SELECT sum(umsatz), anteil,
(sum(umsatz)*100/Gesamt_umsatz) as Prozent
FROM
(SELECT k.nachName as kunde, sum(u.umsatz) as Umsatz,
ntile(4) over (order by sum(u.umsatz)) as Anteil
FROM d_kunde K, f_Umsatz U
WHERE k.kunden_id = u.kunden_id
GROUP by K.nachName),
(SELECT sum(u.umsatz) as Gesamt_Umsatz
FROM
f_Umsatz U) GROUP by anteil,Gesamt_umsatz;
Parallel
Sekunden
P0
19,3
P2
10,6
P4
6,9
P8
7,2
P16
6,2
Beispielabfrage21: Durchschnittliche Bestellquote eines Kunden über 3
Monate?
SELECT
k.nachName,
z.Jahr_Nummer as Jahr,
z.Monats_Nummer as Mon,
sum(u.umsatz) as Umsatz,
sum(avg(u.umsatz)) over
(ORDER by K.nachName, z.Jahr_Nummer,
z.Jahr_Nummer Rows 0 Preceding) as Mov_3M_AVG
FROM d_kunde K, F_Umsatz U, D_zeit Z
WHERE
k.kunden_id = u.kunden_id
AND
Document1
12 /41
Z.zeit_id = u.zeit_id
AND
Z.Jahr_Nummer in (2011,2010)
AND
k.nachname = 'Bauer'
GROUP by K.nachName, z.Jahr_Nummer, z.Monats_Nummer
ORDER by z.Jahr_Nummer, z.Monats_Nummer;
Parallel
Sekunden
P0
1,2
P2
1,0
P4
0,5
P8
2,8
P16
2,1
Beispielabfrage 22: - CUBE
(Analytische Funktion: Ausgabe zusätzlicher Ergebniszeilen für
die jeweiligen Ergebnislevel)
SELECT
a.gruppe_name,
Region,
Land,
sum(u.menge),
grouping(gruppe_name) as AG,
grouping(Region) as RE
FROM
d_artikel a,
f_umsatz U,
d_region R
WHERE
U.artikel_id = a.artikel_id
AND
R.Region_id = U.Region_id
AND
Land = 'Schleswig Holstein'
GROUP by cube (gruppe_name,Region,land);
Parallel
Sekunden
P0
8,6
P2
4,4
P4
2,1
P8
2,3
P16
2,1
Beispielabfrage23 Vergleiche Umsätze mit Vorjahreszeitraum
SELECT
k.nachName,
z.Jahr_Nummer as Jahr,
z.Monats_Nummer as Mon,
sum(u.umsatz) as Umsatz,
lag(sum(u.umsatz),12) over (ORDER by z.Jahr_Nummer,
z.Monats_Nummer) as vorjahr
FROM D_kunde k, F_Umsatz U, D_zeit Z
WHERE
k.kunden_id = u.kunden_id
AND
Z.zeit_id
= u.zeit_id
AND
z.Jahr_nummer in (2010,2011)
AND
k.nachname = 'Bauer'
group by K.nachName, z.Jahr_Nummer, z.Monats_Nummer
order by z.Jahr_Nummer, z.Monats_Nummer;
Parallel
P0
P2
P4
P8
P16
Sekunden
1,28
1,0
2,6
0,8
2,1
Beispielabfrage 24 Year-To-Date. Kumulierung der Monatsumsätze von
Jahresbeginn an
select
z.Jahr_nummer Jahr,
z.MONAT_DESC
Monat,
sum(u.umsatz) Umsatz,
sum(sum(u.umsatz)) over (PARTITION by z.Jahr_nummer order
by z.MONATS_NUMMER) year_to_date
from
f_umsatz u,
d_zeit z
where
z.zeit_id = u.zeit_id
group by
z.Jahr_nummer,
z.MONATS_NUMMER,
z.MONAT_DESC ;
Beispielabfrage 25 Ausgabe von Summenzeilen einer Aggregation
(GROUP BY ROLLUP)
SELECT
artikel_name Artikel,
gruppe_name Prod_Grp,
sum(U.Umsatz) AS Umsatz
FROM
f_umsatz U, d_artikel A
WHERE
U.artikel_id = a.artikel_id
GROUP by ROLLUP
(a.gruppe_name,a.artikel_name)
ORDER by
a.gruppe_name
Beispielabfrage 26 Verwendung von Grouping-Sets
[Analytische Funktion: Ausgeben zusätzlicher
„Steuerinformation“ für „programmiertes“ Auslesen des
Ergebnisses]
SELECT
artikel_name
AS
Artikel,
gruppe_name
AS
Gruppe ,
sparte_name
AS
Sparte ,
Data Warehouse Technik im Fokus - Skripte in Kurzform
sum(U.Umsatz) AS
Umsatz ,
GROUPING(Artikel_name) AS
Art_g ,
GROUPING(gruppe_name) AS
Grp_g ,
GROUPING(Sparte_name) AS
Spr_g ,
GROUPING_ID(artikel_name ,gruppe_name,sparte_name
grouping_id
FROM
f_umsatz U, d_artikel A
WHERE
U.artikel_id = a.artikel_id
GROUP by CUBE
(a.sparte_name, a.gruppe_name,a.artikel_name)
HAVING
GROUPING(Artikel_name) = 1 OR
GROUPING(gruppe_name) = 1 OR
GROUPING(Sparte_name) = 1
ORDER by
) AS
GROUPING(Artikel_name),GROUPING(gruppe_name),GROUPING(Sparte_n
ame)
Document1
13 /41
Data Warehouse Technik im Fokus - Skripte in Kurzform
Tabellen
Allgemeiner Umgang mit Tabellen
Relevante Fragestellungen
Logging / Nologging -> möglichst umgehen und ausschalten
Grössen und Mengen
Storage-Verhalten von Tabellen (PCTFREE) -> möglichst 0
-> möglichst viel in einem Block speichern
Temporäre Tabellen im Rahmen des ETL-Prozesses (CTAS)
Logging/Nologging-Modus für eine einzelne Tabelle ein-/ausschalten
alter table wh_transaktionen nologging;
Allgemeine Informationen
14 /41
t.AVG_SPACE,
t.AVG_ROW_LEN,
t.NUM_ROWS,
t.pct_free,
t.compression,
s.EXTENTS,
s.bytes seg_bytes,
e.blocks ext_blks,
e.bytes ext_bytes
from user_segments
where t.TABLE_NAME
and e.SEGMENT_NAME
and t.TABLE_NAME =
s, user_tables t, user_extents e
= s.segment_name
= s.SEGMENT_NAME
'F_UMSATZ';
Relevante Dictionary Views für Tabellen
USER_TAB_STATISTICS
USER_TAB_PARTITIONS
user_tab_columns
user_tablespaces
USER_TABLES
SYS.V$OBJECT_USAGE
User_extents
User_segments
select table_name,blocks,num_rows,logging from user_tables;
Tabellengrößen und Platzverbrauch
select table_name, pct_free,blocks,blocks/1000000*8
GB,num_rows, compression,cache,empty_blocks, TABLESPACE_NAME
from user_tables;
(Achtung: Die Inhalte sind nur bei aktualisierten Statistiken
gefüllt und richtig.)
Blick in die Column-Struktur einer Tabellen / Distinct Values Nulls etc
select TABLE_NAME,COLUMN_NAME,substr(DATA_TYPE,1,20)
Type,NUM_NULLS,NUM_DISTINCT,USER_STATS from user_tab_columns
where table_name = 'F_UMSATZ';
(auf aktuelle Statistiken achten)
TABLE_NAME
----------F_UMSATZ
F_UMSATZ
F_UMSATZ
F_UMSATZ
F_UMSATZ
F_UMSATZ
F_UMSATZ
F_UMSATZ
COLUMN_NAME
-------------ARTIKEL_ID
KUNDEN_ID
ZEIT_ID
REGION_ID
KANAL_ID
UMSATZ
MENGE
UMSATZ_GESAMT
TYPE
NUM_NULLS NUM_DISTINCT USE
------------- ---------- --------NUMBER
0
129 NO
NUMBER
0
1031 NO
DATE
0
6001 NO
NUMBER
0
7020 NO
NUMBER
0
7 NO
NUMBER
0
4000 NO
NUMBER
0
100 NO
NUMBER
0
61832 NO
Anlegen einer leeren Tabelle mit bestimmter Struktur
create table abc_0 as select * from abc where rownum < 1;
Anlegen von temporären Tabellen
create global temporary table ABC_T on commit preserve rows as
select * from ABC;
Spaltennamen nchträglich ändern
Alter Table F_UMSATZ rename column ALTER_NAME to NEUER_NAME;
Ungenutzten Platz freigeben und komprimieren
alter table F_UMSATZ enable row movement;
alter table F_UMSATZ shrink space cascade;
Parallel
Sekunden
P2
480 (8 Minuten)
create table f_umsatz_tmp pctfree 0 as select * from f_Umsatz;
Parallel
P2
Sekunden
33
create table F_UMSATZ_comp compress as select * from
F_UMSATZ;
Parallel
Sekunden
P2
99,7
Ergebnisse (nach Aktualisierung der Statistiken):
TABLE_NAME PCT_FREE BLOCKS
(1)F_UMSATZ
10 276890
(2)F_UMSATZ
10 276045
(3)F_UMSATZ_TMP
0 249137
(4)F_UMSATZ_COMP
0 235724
GB NUM_ROWS COMPRESS EMPTY_BLOCKS
2.21512 51200000 DISABLED
0
2.20836 51200000 DISABLED
0
1.993096 51200000 DISABLED
0
1.885792 51200000 ENABLED
0
Zu (1) F_umsatz vor alter … shrink
Zu (2) F_umsatz nach alter shrink -> 0,3% Ersparnis
Zu (3) Kopie von F_Umsatz mit PCT_FREE = 0 -> 9,9 % Ersparnis
Zu (4) Standard-Komprimierung -> ~15% gegenü. (1) und ~6% gegenü. (3)
(Der geringe Komprimierungs-Faktor erklärt sich aus der starken
Selektivität der Zufalls-generierten Testdaten mit fehlenden NULL-Werten
und sehr großer Verteilung der Daten)
Blocknummern auslesen
select region_id, dbms_rowid.rowid_block_number(rowid) blk_num
from d_region
order by blk_num;
Tablespace mit Datafile anlegen
CREATE SMALLFILE TABLESPACE "TIF" DATAFILE
'D:\ORA\ORADATA\ORCL\TIF' SIZE 3072M LOGGING EXTENT MANAGEMENT
LOCAL SEGMENT SPACE MANAGEMENT AUTO
Größe von Tabellen, Segmenten, Extents auslesen
select segment_name, bytes,blocks,extents from user_segments
where segment_type = 'TABLE';
select SEGMENT_NAME,EXTENT_ID,BYTES,BLOCKS from user_extents
where SEGMENT_NAME like '%T';
select
t.TABLE_NAME,
t.blocks,
t.EMPTY_BLOCKS,
Document1
Umgang mit Constraints
Abfragen auf bestehende Constraints im aktuellen Schema
select constraint_name,CONSTRAINT_TYPE,TABLE_NAME,STATUS
user_constraints;
from
Status-Werte in der Abfrage können sein
C (check constraint on a table)
P (primary key)
U (unique key)
R (referential integrity)
V (with check option, on a view)
O (with read only, on a view)
Ausschalte / Einschalten von Constraints
alter table table_name DISABLE constraint constraint_name;
alter Table D_Zeit disable constraint PK_ZEIT;
alter Table D_Zeit enable constraint PK_ZEIT;
Relevante Dictionary Views
user_constraints
Compression
Relevante Fragestellungen
Unterschied Advanced Compression / Standard Compression
Erzeugung einer komprimierten Tabelle
Ursachen der unterschiedlich hohen Komprimierungsrate
Selektivität der Columns abfragen
(Siehe auch Hinweise und ausgeführtes Beispiel unter dem
Abschnitt Tabellen)
Anlegen einer komprimierten Tabelle
CREATE TABLE tab_name(…) COMPRESS
create table F_UMSATZ_comp compress
F_UMSATZ;
as select * from
Komprimieren eines Tablespace
CREATE TABLESPACE ... COMPRESS;
Prüfen, ob Tabellen komprimierte sind
select table_name, compression from user_tables order by
table_name;
Tabellen und Partitionen komprimieren
ALTER TABLE MOVE COMPRESS
ALTER TABLE MOVE PARTITION COMPRESS
Komprimierte Tabelle aus seiner unkomprimierten erstellen
create table bestellung_comp compress as select * from
bestellung;
Komprimierungsgrad für bestimmte Tabellen auslesen
select table_name, pct_free,blocks,blocks/1000000*8
GB,num_rows, compression,cache,empty_blocks from user_tables
where
table_name like 'BEST%' or
table_name like 'LIEFE%';
Relevante Dictionary Views für Compression
user_tables
Data Warehouse Technik im Fokus - Skripte in Kurzform
15 /41
PARTITION oct11 VALUES LESS THAN (TO_DATE('2011-11-01','SYYYY-MM-DD')),
PARTITION nov11 VALUES LESS THAN (TO_DATE('2011-12-01','SYYYY-MM-DD')),
Partitioning
PARTITION dec11 VALUES LESS THAN
(TO_DATE('2012-01-01','SYYYY-MM-DD')),
PARTITION next_month VALUES LESS THAN (MAXVALUE));
Relevante Fragestellungen
Skript zum schnellen Erstellen der Testtabelle aus F_UMSATZ
Einsatzgründe für Partitioning (Verwaltung + Performance)
Partition Key
Partitioning-Varianten
Maxvalue-Funktion
Sub-Partitioning
Verteilung von Partitions auf Datafiles
Partition-Struktur-Abfragen
Verwaltung von Partitionen
Wo und warum wird in dem Data Warehouse
Partitioniert






Bei Lese-Aktivitäten / Abfrage-Sutuation hilft das
Partition Pruning. D. h. es müssen nur diejenigen
Partitionen gelesen werden, für die Einschränkungen in der
WHERE-Klausel gelten
Der ETL-Prozesse wird durch das “Partition Exchange Load”Verfahren (PEL) unterstützt.
Ältere Daten in einer Tabelle können auf günstigere
(billigere) Datenträger kopiert werden (ILM, Information
Life Cycle Managemen).PARTITION MOVE.
Durch READ-ONLY Tablespaces kann man verhindern, dass
Teile von Tabellen durch RMAN regelmäßig gesichert warden.
Das spart Kosten. Die Partitionen werden auf Tabellen
ausgelagert (PARTITION EXCHANGE) und dann z. B. über DATA
PUMP einmal als Sicherung weggeschrieben.
Will man das Standard-Compression – Feature nutzen, dann
kann man aktuelle Partitionen unkomprimiert lassen,
während man die Masse der daten (die übrigen Partitionen)
durch einen MOVE komprimiert.
Will mann eine möglichst hohe ONLINE-Verfügbarkeit auch
während des ETL-Laufes haben.
Einschränkung auf 1 Jahr.
insert into f_umsatz_Range select * from f_umsatz where
zeit_ID > to_date('28-FEB-10', 'DD-MON-YY') and
zeit_ID < to_date('01-JAN-12', 'DD-MON-YY')
Skript Beispiel Range Partitioning Beispielskript F_BESTELLUNG_RANGE
[Beispiel analog zu vorherigem Beispiel, daher verkleinert]
CREATE TABLE F_bestellung_part_range
(
SUMME
NUMBER(14,0),
MENGE
NUMBER(14,0),
BESTELLDATUM
DATE,
FK_ARTIKEL_ID
NUMBER,
FK_KUNDEN_ID
NUMBER,
FK_ORT_ID
NUMBER,
FK_DATUM_ID
NUMBER,
auftragsart
VARCHAR2(30)
)
PARTITION BY RANGE (bestelldatum) (
PARTITION jan11 VALUES LESS THAN (TO_DATE('2011-02-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION feb11 VALUES LESS THAN (TO_DATE('2011-03-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION mar11 VALUES LESS THAN (TO_DATE('2011-04-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION apr11 VALUES LESS THAN (TO_DATE('2011-05-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION mai11 VALUES LESS THAN (TO_DATE('2011-06-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION jun11 VALUES LESS THAN (TO_DATE('2011-07-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION jul11 VALUES LESS THAN (TO_DATE('2011-08-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION aug11 VALUES LESS THAN (TO_DATE('2011-09-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION sep11 VALUES LESS THAN (TO_DATE('2011-10-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION oct11 VALUES LESS THAN (TO_DATE('2011-11-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION nov11 VALUES LESS THAN (TO_DATE('2011-12-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
PARTITION
PARTITION
PARTITION
PARTITION
dec11 VALUES LESS
jan12 VALUES LESS
feb12 VALUES LESS
next_month VALUES
THAN
THAN
THAN
LESS
(TO_DATE('2012-01-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
(TO_DATE('2012-02-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
(TO_DATE('2012-03-01', 'SYYYY-MM-DD')) TABLESPACE DWH_SPINDEL,
THAN (MAXVALUE) TABLESPACE DWH_SPINDEL);
Beispielabfrage mit Einschränkung auf Zeit
SELECT sum(UMSATZ) Umsatz
FROM F_UMSATZ_range
WHERE
zeit_ID = to_date('10.03.2011','DD.MM.YYYY')
UMSATZ
---------13883392
Parallel
Sekunden
P0 ohne Range-Partitioning
3,38
P0 mit Range-Partitioning
0,1
MAXVALUE zum Aufnehmen von Werten ohne Zuordnung
CREATE TABLE table orders ( ... )
) PARTITION BY RANGE (ord_date) (
PARTITION p_first VALUES LESS THAN (to_date('2007-01-01')),
[...],
PARTITION p_last VALUES LESS THAN (maxvalue))
Skript Beispiel Range Partitioning nach Alphabet
CREATE TABLE kunde_part_range_alpha
(
kundennummer NUMBER,
vorname
VARCHAR2(20),
kundenname
VARCHAR2(40)
)
PARTITION BY RANGE (kundenname)
(
PARTITION kunde_ae VALUES LESS THAN
part_range1,
PARTITION kunde_fl VALUES LESS THAN
part_range2,
PARTITION kunde_mr VALUES LESS THAN
part_range3,
PARTITION kunde_sz VALUES LESS THAN
part_range4
);
('F%') TABLESPACE
('M%') TABLESPACE
('S%') TABLESPACE
(MAXVALUE) TABLESPACE
Erstellen Hash Partitioned Table au seiner anderen
Was wird partitioniert




Die großen Bewegungsdatentabellen
Die großen Fakten-Tabellen
Tabellen, die man auch während des ETL-Laufes online
lassen will
Tabellen mit mehr als ~ 5 Millionen Sätzen (Dieses Aussage
ist vage, da die Abfrage-Performance von den
Maschinengrößen abhängt.
Partitioning-Varianten
Skript Beispiel Range Partitioning Beispielskript F_UMSATZ_RANGE
CREATE TABLE f_umsatz_range
(ARTIKEL_ID
NUMBER(10),
KUNDEN_ID
NUMBER(10),
ZEIT_ID
DATE,
REGION_ID
NUMBER(10),
KANAL_ID NUMBER(10),
UMSATZ
NUMBER(10),
MENGE
NUMBER(10),
UMSATZ_GESAMT
NUMBER(10)
)
PARTITION BY RANGE (ZEIT_ID) (
PARTITION jan10 VALUES LESS THAN
(TO_DATE('2010-02-01','SYYYY-MM-DD')),
PARTITION feb10 VALUES LESS THAN
Document1
mar10
apr10
mai10
jun10
jul10
aug10
sep10
oct10
nov10
dec10
jan11
feb11
mar11
apr11
mai11
jun11
jul11
aug11
sep11
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
Allgemeines Hash-Partitioning-Beispiel
CREATE TABLE F_BESTELLUNGEN_HASH
(
SUMME
NUMBER(14,0),
MENGE
NUMBER(14,0),
BESTELLDATUM DATE,
FK_ARTIKEL_ID NUMBER,
FK_KUNDEN_ID
NUMBER,
FK_ORT_ID NUMBER,
FK_DATUM_ID
NUMBER)
PARTITION BY HASH (BESTELLDATUM)
PARTITIONS 64 pctfree 0;
Skript Beispiel Hash Partitioning und Tablespace-/Datafile-Zuordnung
CREATE
CREATE
CREATE
CREATE
(TO_DATE('2010-03-
01','SYYYY-MM-DD')),
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
Create table F_Umsatz_Hash
PARTITION BY HASH (KUNDEN_ID)
PARTITIONS 64 pctfree 0
As select * from f_Umsatz;
(TO_DATE('2010-04-01','SYYYY-MM-DD')),
(TO_DATE('2010-05-01','SYYYY-MM-DD')),
(TO_DATE('2010-06-01','SYYYY-MM-DD')),
(TO_DATE('2010-07-01','SYYYY-MM-DD')),
(TO_DATE('2010-08-01','SYYYY-MM-DD')),
(TO_DATE('2010-09-01','SYYYY-MM-DD')),
(TO_DATE('2010-10-01','SYYYY-MM-DD')),
(TO_DATE('2010-11-01','SYYYY-MM-DD')),
(TO_DATE('2010-12-01','SYYYY-MM-DD')),
(TO_DATE('2011-01-01','SYYYY-MM-DD')),
(TO_DATE('2011-02-01','SYYYY-MM-DD')),
(TO_DATE('2011-03-01','SYYYY-MM-DD')),
(TO_DATE('2011-04-01','SYYYY-MM-DD')),
(TO_DATE('2011-05-01','SYYYY-MM-DD')),
(TO_DATE('2011-06-01','SYYYY-MM-DD')),
(TO_DATE('2011-07-01','SYYYY-MM-DD')),
(TO_DATE('2011-08-01','SYYYY-MM-DD')),
(TO_DATE('2011-09-01','SYYYY-MM-DD')),
(TO_DATE('2011-10-01','SYYYY-MM-DD')),
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
T1
T2
T3
T4
DATAFILE
DATAFILE
DATAFILE
DATAFILE
'F:\ORA_DATA\T1.dbf'
'F:\ORA_DATA\T2.dbf'
'F:\ORA_DATA\T3.dbf'
'F:\ORA_DATA\T4.dbf'
SIZE
SIZE
SIZE
SIZE
10M;
10M;
10M;
10M;
CREATE TABLE F_BESTELLUNGEN_HASH_E
(
SUMME
NUMBER(14,0),
MENGE
NUMBER(14,0),
BESTELLDATUM
DATE,
FK_ARTIKEL_ID
NUMBER,
FK_KUNDEN_ID
NUMBER,
FK_ORT_ID
NUMBER,
FK_DATUM_ID
NUMBER)
PARTITION BY HASH (BESTELLDATUM)
PARTITIONS 4 pctfree 0
STORE IN (T1, T2, T3, T4);
Bitmap-Indexe auf Hash-partitionierte Tabelle
Create bitmap index idx_ARTIKEL_ID_BM_H on
F_BESTELLUNGEN_HASH(FK_ARTIKEL_ID) local;
Create bitmap index idx_ZEIT_ID_BM_H on F_BESTELLUNGEN_HASH
(FK_DATUM_ID) local;
Data Warehouse Technik im Fokus - Skripte in Kurzform
Create bitmap index idx_KUNDE_ID_BM_H on F_BESTELLUNGEN_HASH
(FK_KUNDEN_ID) local;
Create bitmap index idx_REGION_ID_BM_H on F_BESTELLUNGEN_HASH
(FK_ORT_ID) local;
Drop Index
DROP
DROP
DROP
DROP
index
index
index
index
idx_ARTIKEL_ID_BM_H;
idx_ZEIT_ID_BM_H ;
idx_KUNDE_ID_BM_H;
idx_REGION_ID_BM_H;
Skript Beispiel List Partitioning
CREATE TABLE bestellung_part_list
(
bestellnr
NUMBER(10) NOT NULL,
kundencode
NUMBER(10),
bestelldatum
DATE,
lieferdatum
DATE,
bestell_total
NUMBER(12,2),
auftragsart
VARCHAR2(30),
vertriebskanal NUMBER
)
PARTITION BY LIST (auftragsart)
(
PARTITION produkt VALUES ('ARTIKEL','TAUSCHWARE'),
PARTITION service VALUES ('SERVICE','REISE'),
PARTITION storno VALUES ('RETOURE','KOMMISSION'),
PARTITION andere VALUES (DEFAULT)
);
Skript Beispiel für Sub-Partition (Range-List)
CREATE TABLE f_umsatz_range_list
(ARTIKEL_ID
NUMBER(10),
KUNDEN_ID
NUMBER(10),
ZEIT_ID
DATE,
REGION_ID
NUMBER(10),
KANAL_ID NUMBER(10),
UMSATZ
NUMBER(10),
MENGE
NUMBER(10),
UMSATZ_GESAMT
NUMBER(10)
)
PARTITION BY RANGE (ZEIT_ID)
SUBPARTITION BY LIST (KANAL_ID) SUBPARTITION
TEMPLATE
(
SUBPARTITION kanal1 VALUES (1),
SUBPARTITION kanal2 VALUES (2),
SUBPARTITION kanal3 VALUES (3),
SUBPARTITION kanal4 VALUES (4),
SUBPARTITION kanal5 VALUES (5),
SUBPARTITION kanal6 VALUES (6),
SUBPARTITION kanal7 VALUES (7)
)
(
PARTITION jan10 VALUES LESS THAN
(TO_DATE('2010-02-01','SYYYY-MM-DD')),
PARTITION feb10 VALUES LESS THAN
(TO_DATE('2010-03-01','SYYYY-MM-DD')),
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
mar10
apr10
mai10
jun10
jul10
aug10
sep10
oct10
nov10
dec10
jan11
feb11
mar11
apr11
mai11
jun11
jul11
aug11
sep11
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
LESS
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
(TO_DATE('2010-04-01','SYYYY-MM-DD')),
(TO_DATE('2010-05-01','SYYYY-MM-DD')),
(TO_DATE('2010-06-01','SYYYY-MM-DD')),
(TO_DATE('2010-07-01','SYYYY-MM-DD')),
(TO_DATE('2010-08-01','SYYYY-MM-DD')),
(TO_DATE('2010-09-01','SYYYY-MM-DD')),
(TO_DATE('2010-10-01','SYYYY-MM-DD')),
(TO_DATE('2010-11-01','SYYYY-MM-DD')),
(TO_DATE('2010-12-01','SYYYY-MM-DD')),
(TO_DATE('2011-01-01','SYYYY-MM-DD')),
(TO_DATE('2011-02-01','SYYYY-MM-DD')),
(TO_DATE('2011-03-01','SYYYY-MM-DD')),
(TO_DATE('2011-04-01','SYYYY-MM-DD')),
(TO_DATE('2011-05-01','SYYYY-MM-DD')),
(TO_DATE('2011-06-01','SYYYY-MM-DD')),
(TO_DATE('2011-07-01','SYYYY-MM-DD')),
(TO_DATE('2011-08-01','SYYYY-MM-DD')),
(TO_DATE('2011-09-01','SYYYY-MM-DD')),
(TO_DATE('2011-10-01','SYYYY-MM-DD')),
PARTITION oct11 VALUES LESS THAN
(TO_DATE('2011-11-01','SYYYY-MM-DD')),
PARTITION nov11 VALUES LESS THAN
(TO_DATE('2011-12-01','SYYYY-MM-DD')),
PARTITION dec11 VALUES LESS THAN
(TO_DATE('2012-01-01','SYYYY-MM-DD')),
PARTITION next_month VALUES LESS THAN (MAXVALUE));
Beispielabfrage auf Range/List
SELECT /*+ no cache, no parallel */ sum(UMSATZ) Umsatz
FROM F_UMSATZ[_RANGE[_LIST]] U, D_vertriebskanal V
WHERE
u.kanal_id = v.kanal_id
and zeit_ID = to_date('10.03.2011','DD.MM.YYYY')
and V.vertriebskanal = 'Shop';
Parallel
Sekunden
Physical Reads
P0 ohne Partitioning
3,38
276045
P0 mit Range-Partitioning
0,09
782
P0 mit Range/List0,08
248
Partitioning
(Diese Ergebnisse lassen nur schwer Unterschiede erkennen,
obwohl das System eine Tabelle mit über 52 Millionen Sätzen
liest. Daher ist das Auslesen der „Physical Reads“ hilfreich.
-> set autotrace on)
Zweites Range/List – Beispiel
[Analog dem ersten Beispiel, daher verkleinert]
CREATE TABLE F_bestellung_part_range_list (
SUMME
NUMBER(14,0),
MENGE
NUMBER(14,0),
BESTELLDATUM DATE,
FK_ARTIKEL_ID
NUMBER,
FK_KUNDEN_ID
NUMBER,
FK_ORT_ID
NUMBER,
FK_DATUM_ID
NUMBER,
auftragsart
VARCHAR2(30)
)
PARTITION BY RANGE (bestelldatum)
SUBPARTITION BY LIST (auftragsart) SUBPARTITION TEMPLATE
(
SUBPARTITION produkt VALUES ('ARTIKEL','TAUSCHWARE','PRODUKT'),
SUBPARTITION service VALUES ('SERVICE','REISE'),
Document1
16 /41
SUBPARTITION storno
SUBPARTITION andere
)
(
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
PARTITION
);
jan11 VALUES LESS
feb11 VALUES LESS
mar11 VALUES LESS
apr11 VALUES LESS
mai11 VALUES LESS
jun11 VALUES LESS
jul11 VALUES LESS
aug11 VALUES LESS
sep11 VALUES LESS
oct11 VALUES LESS
nov11 VALUES LESS
dec11 VALUES LESS
jan12 VALUES LESS
feb12 VALUES LESS
next_month VALUES
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
THAN
LESS
VALUES ('RETOURE','KOMMISSION'),
VALUES (DEFAULT)
(TO_DATE('2011-02-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-03-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-04-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-05-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-06-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-07-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-08-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-09-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-10-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-11-01', 'SYYYY-MM-DD'))
(TO_DATE('2011-12-01', 'SYYYY-MM-DD'))
(TO_DATE('2012-01-01', 'SYYYY-MM-DD'))
(TO_DATE('2012-02-01', 'SYYYY-MM-DD'))
(TO_DATE('2012-03-01', 'SYYYY-MM-DD'))
THAN (MAXVALUE) TABLESPACE DWH_SPINDEL
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
TABLESPACE
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
DWH_SPINDEL,
Skript Beispiel Reference Partitioning
CREATE TABLE bestellung_part_range_ref (
bestellnr
NUMBER(10) NOT NULL,
kundencode
NUMBER(10),
bestelldatum
DATE,
lieferdatum
DATE,
bestell_total
NUMBER(12,2),
auftragsart
VARCHAR2(30),
vertriebskanal NUMBER
)
PARTITION BY RANGE (bestelldatum)
PARTITION dez09 VALUES LESS THAN (TO_DATE('2010-01-01',
'SYYYY-MM-DD')) TABLESPACE part,
PARTITION jan10 VALUES LESS THAN (TO_DATE('2010-02-01',
'SYYYY-MM-DD')) TABLESPACE part,
PARTITION feb10 VALUES LESS THAN (TO_DATE('2010-03-01',
'SYYYY-MM-DD')) TABLESPACE part,
PARTITION mar10 VALUES LESS THAN (TO_DATE('2010-04-01',
'SYYYY-MM-DD')) TABLESPACE part,
PARTITION apr10 VALUES LESS THAN (TO_DATE('2010-05-01',
'SYYYY-MM-DD')) TABLESPACE part,
PARTITION mai10 VALUES LESS THAN (TO_DATE('2010-06-01',
'SYYYY-MM-DD')) TABLESPACE part
);
ALTER TABLE bestellung_part_range_ref ADD CONSTRAINT
pk_bestellnr_part_range_ref PRIMARY KEY (bestellnr);
CREATE TABLE best_position_part_range_ref (
posnummer
NUMBER(10) NOT NULL,
artikelnr
NUMBER(10) NOT NULL,
bestellnr
NUMBER(10) NOT NULL,
bestellmenge NUMBER(10),
CONSTRAINT fk_bestellnr_part_range_ref FOREIGN KEY
(bestellnr) REFERENCES bestellung_part_range_ref (bestellnr)
)
PARTITION BY REFERENCE (fk_bestellnr_part_range_ref);
Skript Beispiel Interval-Partition mit Monatspartitionen
CREATE TABLE BESTELLUNG (
BESTELLNR NUMBER(10) NOT NULL,
KUNDENCODE NUMBER(10),
BESTELLDATUM DATE,
LIEFERDATUM DATE,
BESTELL_TOTAL NUMBER(12, 2),
AUFTRAGSART VARCHAR2(30),
ORDER_ID NUMBER
)
PARTITION BY RANGE (BESTELLDATUM)
INTERVAL(NUMTOYMINTERVAL(1,'MONTH'))
(
PARTITION Jan07
VALUES LESS THAN (TO_DATE(' 2007-01-31 00:00:00', 'SYYYYMM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLESPACE TS_PAR,
PARTITION Feb07
VALUES LESS THAN (TO_DATE(' 2007-02-28 00:00:00', 'SYYYY-MMDD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLESPACE TS_PAR
);
[Wenn ENABLE ROW MOVEMENT* verwendet wird, migrieren
Datensätze bei Änderung der Werte automatisch in die
jeweiligen Partitionen]
Skript Beispiel Interval-Partition mit numerischer Bereichsangabe
create table test
(MA_NR number(6),
NACHNAME varchar2(30),
GEHALT number(6))
partition by range(GEHALT)
Interval (5000)
(
partition p1 values less than (5000),
partition p2 values less than (10000),
partition p3 values less than (15000),
partition p4 values less than (20000));
Ändern bestehender Range-Partition-Tables auf Interval Partitioning
ALTER TABLE table_name SET INTERVAL (interval value);
Skript Beispiel Virtuel Column Partition
CREATE TABLE "BESTELLUNG_VIRTUELL"
(
"BESTELLNR"
NUMBER(10) NOT NULL,
"KUNDENCODE"
NUMBER(10),
"BESTELLDATUM"
DATE,
"LIEFERDATUM"
DATE,
"BESTELL_TOTAL" NUMBER(12, 2),
"AUFTRAGSART"
VARCHAR2(30),
"VERTRIEBSKANAL" NUMBER,
Data Warehouse Technik im Fokus - Skripte in Kurzform
Bonusgewicht as (Bestell_Total*VertriebsKanal/10)
)
PARTITION BY RANGE (Bonusgewicht)
(
PARTITION Gruppe_20 VALUES LESS THAN (20),
PARTITION Gruppe_50 VALUES LESS THAN (50),
PARTITION Gruppe_100 VALUES LESS THAN (100),
PARTITION Gruppe_MAX VALUES LESS THAN (MAXVALUE));
Zuweisen unterschiedlicher Tablespaces
ALTER TABLE Bestellung
ADD PARTITION DEZ08
VALUES LESS THAN
(to_date('2008-12-31 00:00:00','SYYYY-MM-DD HH24:MI:SS',
'NLS_CALENDAR=GREGORIAN'))
TABLESPACE TS_PAR DEPENDENT TABLES (Best_Position(PARTITION
DEZ08_Child TABLESPACE TS_DEZ08_Child));
Abfragen auf Partitionen
Partitiondaten direkt abfragen
SELECT * FROM Bestellung PARTITION (Apr08);
SELECT * FROM Bestellung SUBPARTITION (Apr08_PRODUKT);
Grössen, Mengen und Namen
select segment_name, TABLESPACE_NAME ,segment_type,
partition_name, BYTES/1000000 MB,BLOCKS from user_segments;
Verteilung von Partitionen auf Tablespaces
select segment_name,Partition_name,TABLESPACE_NAME from
user_segments;
Tabellen,Partition,Rows
SELECT table_name, partition_name, num_rows
user_tab_partitions
FROM
SELECT table_name, partition_name, num_rows
FROM
user_tab_partitions WHERE table_name = 'BESTELLUNG';
SELECT table_name, partition_name, num_rows
FROM
user_tab_partitions WHERE table_name LIKE 'AUFTRAGSART%';
Tabellen,Partition,Rows,Blocks,MegaBytes
SELECT table_name, tablespace_name,partition_name, num_rows,
blocks, ((blocks*8192)/1000000) MegaByte, high_value FROM
user_tab_partitions
Partitionsgrenzen abfragen
SELECT table_name, partition_name, high_value
FROM user_tab_partitions
WHERE table_name IN ('BESTELLUNG','BEST_POSITION')
ORDER BY partition_position, table_name;
Auslesen von Sub Partitions
col subpartition_name format a15
col partition_name format a15
col SUBPARTITION_POSITION format 99999999
SELECT table_name, partition_name, subpartition_name,
subpartition_position FROM user_tab_subpartitions;
SELECT table_name, partition_name, subpartition_name, num_rows
FROM user_tab_subpartitions WHERE table_name = 'BESTELLUNG';
SELECT up.table_name, up.partitioning_type, uc.table_name
ref_table
FROM user_part_tables up,
(select r.table_name, r.constraint_name from
user_constraints uc,
user_constraints r
where uc.constraint_name=r.constraint_name and
uc.owner=r.owner) uc
WHERE
up.ref_ptn_constraint_name = uc.constraint_name(+)
AND up.table_name IN ('BESTELLUNG','BEST_POSITION');
Sich refenzierende Tabellen abfragen / Referen Partitioning
SELECT table_name, partitioning_type,ref_ptn_constraint_name
FROM
user_part_tables
WHERE table_name IN ('BESTELLUNG','BEST_POSITION');
Verwaltung von Partitionen
Partionen hinzufügen
ALTER TABLE BESTELLUNG
ADD PARTITION NOV08
VALUES LESS THAN (to_date('2008-11-30 00:00:00','SYYYY-MM-DD
HH24:MI:SS',
'NLS_CALENDAR=GREGORIAN'))
TABLESPACE TS_PAR
Partitionen auf anderen Tablespace verlagern
ALTER TABLE BESTELLUNG
MOVE PARTITION Jan08
TABLESPACE TS_PAR_Archiv;
ALTER TABLE BESTELLUNG
MOVE SUBPARTITION Jan08_STORNO
TABLESPACE TS_PAR_Archiv_Jan;
Merge von zwei Sub-Partitions
ALTER TABLE BESTELLUNG
MERGE SUBPARTITIONS TELEFON_STORNO, TELEFON_ANDERE
INTO SUBPARTITION TELEFON_OBJEKTE
Document1
17 /41
TABLESPACE TS_PAR;
Ändern Defaults-Tablespace
ALTER TABLE BESTELLUNG
MODIFY DEFAULT ATTRIBUTES FOR PARTITION Jan08
TABLESPACE TS_PAR_JAN ;
Ändern der Werte bei List-Partitioning
ALTER TABLE Bestellung
MODIFY PARTITION Produkt
ADD VALUES ('WARE');
ALTER TABLE Bestellung
MODIFY PARTITION Storno
DROP VALUES ('KOMMISSION');
Umwandeln einer Partion in eine Tabelle
-- Leere Tabelle mit der passenden Struktur erstellen
CREATE TABLE Bestellung_Produkte AS
SELECT * FROM bestellung WHERE 1=2
-- Exchange
ALTER TABLE Bestellung
EXCHANGE PARTITION Produkt
WITH TABLE Bestellung_Produkte;
Umbenennen einer Partition
ALTER TABLE Bestellung RENAME PARTITION Andere TO
Bestellung_Rest;
Truncate einer Partition
ALTER TABLE Bestellung TRUNCATE PARTITION Service DROP
STORAGE;
Aufspalten einer Partition
ALTER TABLE Bestellung SPLIT PARTITION Jan08
AT (to_date('15-JAN-2008','DD-MON-YYYY'))
INTO (PARTITION Jan08_1, PARTITION Jan08_2)
UPDATE GLOBAL INDEXES;
Partition Exchange (Hinzufügen einer Tabelle als weitere Partition)
ALTER TABLE Bestellung EXCHANGE PARTITION Nov08
WITH TABLE Bestellung_temp INCLUDING INDEXES WITHOUT
VALIDATION;
Relevante Dictionary Views für Partitioning
DBA_PART_TABLES Table-Level
DBA_TAB_PARTITIONS
Partition-/Subpartition-Level
DBA_PART_KEY_COLUMNS
Partition-/SubpartitionDBA_SUBPART_KEY_COLUMNS Key-Informationen
DBA_PART_COL_STATISTICS Statistiken und Histogramme per
Partition / Subpartition
USER_IND_PARTITIONS
DBA_SUBPART_COL_STATISTICS
DBA_TAB_SUBPARTITIONS
User_segments
Data Warehouse Technik im Fokus - Skripte in Kurzform
18 /41
Oder
Indexe
Relevante Fragestellungen
Umschlüsselung im DWH
Bitmap / B*Tree Einsatz
Platzverbrauch
Welche Indexe gibt es in einem Schema?
Überprüfen, ob Indexe gebraucht werden
Clustering-Faktor
Lokale Indexe Partitionierung von Indexen
Prefixed / Non-Prefixed Index
Star-Transformation
Wie und wo wird im DWH indiziert?
Umgang mit Indexen während eines Massenloads beim ETL
Wie und wo wird indiziert
1.
2.
DROP Index index_name
CREATE Index index_name
Rebuild Partitioned Index
ALTER TABLE <table_name>
MODIFY PARTITION <partition_name>
REBUILD UNUSABLE LOCAL INDEXES;
Rebuild Sub-Partitioned Index
ALTER TABLE <table_name>
MODIFY SUBPARTITION <subpartition_name>
REBUILD UNUSABLE LOCAL INDEXES;
Verschieben eines Index auf einen anderen Tablespace
ALTER INDEX <index_name>
REBUILD PARTITION <partition_name>
TABLESPACE <new_tablespace_name>;
ALTER TABLE part1
MOVE PARTITION p1 TABLESPACE new_tbsp UPDATE INDEXES
(my_parts_idx (PARTITION p1 TABLESPACE my_tbsp));
Aktualisierung der Index zusammen mit Tabellen-Updates
ALTER TABLE T1 DROP PARTITION P1
UPDATE GLOBAL INDEXES
Einschalten Usage - Monitoring für einen Index
alter index PK_BESTELLNR_PART_RANGE_HASH monitoring usage.
Welcher Index wurde tatsächlich genutzt: Usage - Abfrage
SELECT INDEX_NAME, TABLE_NAME, MONITORING, USED
FROM SYS.V$OBJECT_USAGE;
Clustering Faktor und Anzahl Leaf-Blöcke abfragen
select index_name, tablespace_name, blevel,
leaf_blocks,distinct_keys, clustering_factor from user_indexes
Partitionierung von Indexen
Skript Local Partion Index
Suche nachbestehenden Indexen
Suche nach Indexen bezogen auf eine bestimmte Tabelle
SELECT index_name, partitioned
FROM user_indexes
WHERE table_name = 'BESTELLUNG';
Status-Abfragen
select index_name, status from user_indexes;
Auflisten aller Indexe eines Schemas inkl. Größe
SELECT index_name,Table_name,status, num_rows,index_type,
blevel, leaf_blocks, distinct_keys FROM user_indexes
Auflisten aller lokalen Index
SELECT ip.index_name, ip.partition_position,
ip.partition_name, ip.high_value
FROM user_ind_partitions ip, user_indexes ui
WHERE ip.index_name = ui.index_name
AND ui.table_name = 'BESTELLUNG_PART_RANGE' ORDER BY
index_name, partition_position;
CREATE INDEX idx_region_id ON F_Umsatz_range (region_id)
LOCAL;
Partitionierung der Indexe entsprechend der zugehörigen TablePartionen (Local Partiton Index) und zweisen unterschiedlicher
Tablespaces
CREATE INDEX idx_bestellnr_part_range ON bestellung_part_range
(bestellnr) LOCAL (
PARTITION B0,
PARTITION B1,
PARTITION B2,
PARTITION B3,
PARTITION B4);
Partitionierung des Index unabhängig von den Table-Partitionen (Global
Partition Index)
CREATE INDEX idx_UMSATZ_RANGE on f_umsatz_range (Kunden_id)
GLOBAL
PARTITION BY RANGE (Kunden_id) (
PARTITION index100 VALUES LESS THAN (100),
PARTITION index500 VALUES LESS THAN (500),
PARTITION index1000 VALUES LESS THAN (1000),
PARTITION index_MAX VALUES LESS THAN (MAXVALUE));
SELECT ip.index_name, ip.composite, ip.partition_name,
ip.high_value
FROM user_ind_partitions ip, user_indexes ui
WHERE ip.index_name = ui.index_name
AND ui.table_name = 'BESTELLUNG';
Partitionierte Indexe suchen
Anzeigen des Platzverbrauchs der Indexe
SELECT ip.index_name, ip.composite, ip.partition_name,
ip.high_value
FROM user_ind_partitions ip, user_indexes ui
WHERE ip.index_name = ui.index_name
AND ui.table_name = 'BESTELLUNG';
select
substr(us.segment_name,1,20) Name,
ui.index_type
Typ,
round((us.bytes/1000000),2) Mbyte,
us.tablespace_name TB_Space
from user_segments us, user_indexes ui
where us.segment_type = 'INDEX'
and ui.index_type = 'BITMAP'
and ui.index_name = us.segment_name;
Beispiele für Definitionen (Bitmap / B*tree)
Drop index idx_Bildungsgruppe_BM;
Create bitmap index idx_Bildungsgruppe_BM on
I_Kunde(Bildungsgruppe);
Drop index idx_Bildungsgruppe_BT;
Create index idx_Bildungsgruppe_BT on I_Kunde(Bildungsgruppe);
SELECT sum(UMSATZ) Umsatz
FROM F_UMSATZ
WHERE
zeit_ID = to_date('10.03.2011','DD.MM.YYYY')
/
Parallel
Sekunden
P0 ohne Bitmap-Index
3,38
P0 mit Bitmap-Index
0,2
Behandlung von Indexen beim Laden
1.
2.
3.
Document1
INDEX auf Unusable setzen
[Alter index index_name usable]
ETL-Massen-Load durchführen
INDEX Rebuild
[Alter index index_name rebuild]
SELECT index_name, partitioned
FROM user_indexes
WHERE table_name = 'BESTELLUNG';
Rebuild lokaler Index
ALTER TABLE <table_name>
MODIFY PARTITION <partition_name>
REBUILD UNUSABLE LOCAL INDEXES;
Rebuild Sub Partition Index
ALTER TABLE <table_name>
MODIFY SUBPARTITION <subpartition_name>
REBUILD UNUSABLE LOCAL INDEXES;
Verschieben auf anderen Tablespace
ALTER INDEX <index_name>
REBUILD PARTITION <partition_name>
TABLESPACE <new_tablespace_name>;
Relevante Dictionary Views für Indexing
USER_IND_STATISTICS
INDEX_HISTOGRAM
USER_IND_PARTITIONS
USER_INDEXTYPES
USER_IND_COLUMNS
USER_IND_PARTITIONS
USER_INDEXES
INDEX_STATS
SYS.V$OBJECT_USAGE
USER_INDEXTYPE_OPERATORS
USER_IND_EXPRESSIONS
USER_IND_SUBPARTITIONS
Data Warehouse Technik im Fokus - Skripte in Kurzform
Star Schema
Allgemeine Regeln









Star Schema mit dnormalisierten Dimensionen verwenden und
kein Snowflake
-> intuitiver für Anwender und weniger Joins
Fakten-Tabelle so granular wie möglich aufbauen.
Orientieren an der Granularität der Vorsysteme
-> Schafft mehr Flexibilität in den Auswertungen.
Verwandte Fakten-Tabellen schaffen. Verbindungen über
Dimensionstabellen aufbauen (Conformed Dimensions).
-> Man erhält mehr Abfrage-Kombinationen und mehr Auswahl
für die Endbenutzer.
Operativ genutzte Daten (z. B. Kontaktdaten für
Kampagnen)in separate Dimensionen oder Tabellen auslagern
(1:1- Auslagerung)
Überfrachtete Dimensionen mit zu vielen Attributen
aufspalten in 2 oder mehrere. Die Faktentabelle mit der
großen Masse der Daten ist davon nicht betroffen.
-> macht das Star Schema übersichtlicher
Faktentabellen besitzen i. d. R. Keinen Primary Key. Wenn
doch solche Schlüssel eingeführt werden, dann sind es
technische Schlüssel, die mit dem Ladelauf zusammenhängen,
um eventuell Daten wieder herauszulöschen.
Fakten-Tabellen sind meist Kandidaten für Partitioning.
Dimensionen mit nur einem Attribut in die Fakten-Tabelle
verlagern (Degenerated Dimension.
Star Schema einfach und verständlich halten
o
Level-bezogene Präfixe nutzen
o
Sprechende Column-Namen nutzen
o
Codes vermeiden
Konsistenz, Mengen und Indexe im Star-Schema
Relevante Fragestellungen
Wann zieht die Star Transformation
Voraussetzungen prüfen
Prüfen ob FK der Fakten-Tab in PK der Dimensionen
select count(*) from f_umsatz where artikel_id not in (select
artikel_ID from d_artikel);
Größe der Indexe ausgeben
select segment_name, round((bytes/1000000),2) Mbyte
,tablespace_name from user_segments where segment_type =
'INDEX'
Index-Typen anzeigen
select index_name, index_type from user_indexes;
Größe aller Bitmap-Indexe
select us.segment_name, round((us.bytes/1000000),2) Mbyte
,us.tablespace_name
from user_segments us, user_indexes ui
where us.segment_type = 'INDEX'
and ui.index_type = 'BITMAP'
and ui.index_name = us.segment_name;
Star Transformation aktivieren
alter system set star_transformation_enabled=TRUE;
Menge der WHERE-Bedingungen überprüfen
Star-Query zieht nur, wenn neben den PK/FK-Join-Bedingungen
mindestens 2 zusätzliche einschränkende Bedingungen abgefragt
werden. Die Einschränkungen können auf den FK-Feldern der
Fakten oder auf einem beliebigen Feld der Dimensions-tabellen
liegen. [siehe Beispielabfrage 3]
Document1
19 /41
Data Warehouse Technik im Fokus - Skripte in Kurzform
Materialized Views
Relevante Fragestellungen
Einsatzgründe für Materialized (Verwaltung + Performance)
Definition (Erstellung)
Planung und Konzept
Staleness
Kennzahlen-Systemen (Nested Materialized Views
Rewrite-Fähigkeit
Refresh-Varianten (Log / PCT)
Hilfen/Konzepte für Materialized Views
Allgemeine Hinweise zur Definition von Materialized Views
 Zählfunktionen einbauen Count(*) / Count(feldname)
 Bei Joins i. d. R. die granularsten Hierarchie-Level in der
MAV joinen.
 Aufeinander aufbauende Materialized Views nutzen.
-> Das verhindert redundanten Join-Aufwand bei dem Refresh.
 Im Star-Schema werden die meisten MAVs zwischen Fakten und
den jeweiligen Dimensionen gebildet (auf unterstem Level).
Danach wird die Faktentabelle mit 2 Dimensionen verbunden
und dann mit 3 usw.
20 /41
Beispieldefinition MAV_Artikel_Umsatz
Unterstützte Kennzahlen/
Abfragen
Gesamtumsatz/menge pro
Artikel/Gruppe/Sparte
Aggregiert auf
Artikelgruppe und sparte
„“
drop materialized View Mav_Artikel_umsatz;
[Beispielabfrage 9,11,(19)]
create MATERIALIZED VIEW Mav_artikel_umsatz
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
ENABLE QUERY REWRITE
as
SELECT sum(u.UMSATZ) Umsatz,
sum(u.menge) Menge,
A.Artikel_ID,
count(*)
FROM F_UMSATZ U, D_Artikel A
WHERE
U.Artikel_ID
= A.Artikel_ID
Group by A.Artikel_ID;
Parallel
P4 ohne Partitioning
Sekunden
90
Physical Reads
276045
Beispieldefinition MAV_Region_Umsatz
Unterstützte Kennzahlen/
Abfragen
Gesamtumsatz/menge pro Ort/Kreis/Land/Region
drop materialized View Mav_Region_umsatz;
[Beispielabfrage 4]
Die hier dargestellten Materialized Views sorgen dafür, dass
alle oben beschriebenen Beispielabfragen nur weniger als 0,2
Sekunden benötigen.
 Materialized Views werden Oracle-intern wie Tabellen
behandelt, daher gelten einige der Verhaltensweisen von
Tabellen und auch Abfragen auch für Materialized Views. Um
sie dennoch zu unterscheiden, kann man eine Namenskonvention
(z. B. MAV_...) einführen, wie in diesem Beispiel)
Informationszugriffen planen und dokumentieren
create MATERIALIZED VIEW Mav_Region_umsatz
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
ENABLE QUERY REWRITE
as
SELECT sum(u.UMSATZ) Umsatz,
sum(u.menge) Menge,
R.Region_ID,
count(*)
FROM F_UMSATZ U, D_Region R
WHERE
U.Region_ID = R.Region_ID
Group by R.Region_ID;
Parallel
Sekunden
Physical Reads
P4 ohne
Partitioning
90
276045
Relevante Parameter
ALTER SESSION SET
ALTER SESSION SET
ALTER SESSION SET
query_rewrite_enabled=TRUE;
query_rewrite_enabled=FALSE;
query_rewrite_integrity=STALE_TOLERATED
Beispieldefinition MAV_Kunde_Umsatz
MVIEW suchen
Unterstützte Kennzahlen/Abfragen
Gesamtumsatz/menge pro Kunde/Bildungsgruppe,
Einkommensgruppe, Wohnart, Berufsgruppe
select mview_name,REWRITE_ENABLED,STALENESS,REWRITE_CAPABILITY
from user_mviews;
drop materialized View Mav_Kunde_umsatz;
Größe und Anzahl Zeilen von Mviews abfragen
[Beispielabfrage 20]
select table_name, pct_free,blocks,blocks/1000000*8
GB,num_rows, compression,cache,empty_blocks from user_tables
where upper(table_name) like 'MAV_%';
Beispieldefinition MAV_Zeit_Umsatz
Unterstützte Kennzahlen/Abfragen
Gesamtumsatz pro Tag/Monat/Quartal/Zeit
drop materialized View Mav_Zeit_umsatz;
[Beispielabfrage 5,6,7]
create MATERIALIZED VIEW Mav_Zeit_umsatz
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
ENABLE QUERY REWRITE
as
SELECT sum(u.UMSATZ) Umsatz,
sum(u.menge) Menge,
Z.Zeit_ID,
count(*)
FROM F_UMSATZ U, D_Zeit Z
WHERE
U.Zeit_ID
= Z.Zeit_ID
Group by Z.Zeit_ID;
Parallel
Sekunden
Physical Reads
P4 ohne Partitioning
67
276045
Document1
create MATERIALIZED VIEW Mav_Kunde_umsatz
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
ENABLE QUERY REWRITE
as
SELECT sum(u.UMSATZ) Umsatz,
sum(u.menge) Menge,
k.Kunden_ID,
count(*)
FROM F_UMSATZ U, D_Kunde K
WHERE
U.Kunden_ID = k.Kunden_ID
Group by k.Kunden_ID;
Parallel
Sekunden
Physical Reads
P4 ohne Partitioning
70
276045
Beispieldefinition MAV_Region_Artikel_Umsatz
Unterstützte Kennzahlen/
Abfragen
Gesamtumsatz/menge pro Ort/Kreis/Land/Region
Artikel, Artikelgruppe und -sparte
[Beispielabfrage 11,12,13,14,15,16,(19)]
drop materialized View Mav_Region_Artikel_umsatz;
Data Warehouse Technik im Fokus - Skripte in Kurzform
create MATERIALIZED VIEW Mav_Region_Artikel_umsatz
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
ENABLE QUERY REWRITE
as
SELECT sum(u.UMSATZ) Umsatz,
sum(u.menge) Menge,
R.Region_ID,
a.Artikel_ID,
count(*)
FROM F_UMSATZ U, D_Region R, d_Artikel A
WHERE
U.Region_ID = R.Region_ID and
U.Artikel_ID = A.Artikel_ID
Group by R.Region_ID,a.Artikel_ID;
Parallel
Sekunden
Physical Reads
P4 ohne
Partitioning
12,0
276045
21 /41
as
SELECT sum(u.UMSATZ) Umsatz,
sum(u.menge) Menge,
R.Region_ID,
Z.Zeit_ID,
a.Artikel_ID,
count(*)
FROM F_UMSATZ U, D_Region R, d_Zeit Z, d_artikel A
WHERE
U.Region_ID = R.Region_ID and
U.Artikel_ID = A.Artikel_ID and
U.Zeit_ID
= Z.Zeit_ID
Group by R.Region_ID,z.Zeit_ID,A.Artikel_ID;
Parallel
Sekunden
Physical Reads
P4 ohne
Partitioning
17
276045
Beispiel-Definition
Beispieldefinition MAV_Region_Zeit_Umsatz
Unterstützte Kennzahlen/Abfragen
Gesamtumsatz/menge pro Ort/Kreis/Land/Region
Tag/Monat/Quartal/Jahr
[Beispielabfrage 8]
drop materialized View Mav_Region_Zeit_umsatz;
create MATERIALIZED VIEW Mav_Region_Zeit_umsatz
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
ENABLE QUERY REWRITE
as
SELECT sum(u.UMSATZ) Umsatz,
sum(u.menge) Menge,
R.Region_ID,
Z.Zeit_ID,
count(*)
FROM F_UMSATZ U, D_Region R, d_Zeit Z
WHERE
U.Region_ID = R.Region_ID and
U.Zeit_ID
= Z.Zeit_ID
Group by R.Region_ID,z.Zeit_ID;
Parallel
Sekunden
Physical Reads
P4 ohne
Partitioning
14,0
276045
CREATE MATERIALIZED VIEW MV_Standard
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
ENABLE QUERY REWRITE
AS SELECT
z.jahr_nummer
Jahr,
z.monat_desc
Monat,
sum(u.umsatz)
Summe,
a.artikel_id
ID,
count(u.umsatz)
FROM
f_umsatz u,d_artikel a, d_zeit z
WHERE a.artikel_id = u.artikel_id AND
u.zeit_id = z.datum_id
GROUP BY
z.jahr_nummer, z.monat_desc, a.artikel_id;
Beispiel für eine Partitionierte MAV
CREATE TABLE f_umsatz_Par
(umsatz NUMBER(14,0),
menge NUMBER(14,0),
bestell_datum DATE,
artikel_id NUMBER,
kunde_id NUMBER,
region_id NUMBER,
zeit_id NUMBER)
PARTITION BY RANGE(bestell_datum) )
(PARTITION p_2009_Jan VALUES LESS THAN
(to_date('01.02.2009','dd.mm.yyyy')),
PARTITION p_2009_feb VALUES LESS THAN
(to_date('01.03.2009','dd.mm.yyyy')),
PARTITION p_2009_mar VALUES LESS THAN
(to_date('01.04.2009','dd.mm.yyyy'));
Definition Materialized View Log
Unterstützte Kennzahlen/Abfragen
Gesamtumsatz/menge pro Ort/Kreis/Land/Region
Tag/Monat/Quartal/Jahr
CREATE MATERIALIZED VIEW LOG ON f_umsatz
WITH ROWID, SEQUENCE
(umsatz, menge, umsatz_nach_rabatt, rabatt_wert_firmenkunde,
Rabatt_wert_privatkunde, bestell_datum, artikel_id, kunde_id,
region_id, zeit_id)
INCLUDING NEW VALUES;
drop materialized View Mav_Kunde_Zeit_umsatz;
Löschen Materilized View Log
create MATERIALIZED VIEW Mav_Kunde_Zeit_umsatz
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
ENABLE QUERY REWRITE
as
SELECT sum(u.UMSATZ) Umsatz,
sum(u.menge) Menge,
K.Kunden_ID,
Z.Zeit_ID,
count(*),
count(u.umsatz),
count(u.menge)
FROM F_UMSATZ U, D_Kunde K, d_Zeit Z
WHERE
U.Region_ID = K.Kunden_ID and
U.Zeit_ID
= Z.Zeit_ID
Group by K.Kunden_ID,z.Zeit_ID;
Build Funktionen
Beispieldefinition MAV_Kunde_Zeit_Umsatz
Parallel
P4 ohne Partitioning
Sekunden
3,7
Physical Reads
276045
Beispieldefinition MAV_Region_Zeit_Artikel_Umsatz
Unterstützte Kennzahlen/Abfragen
Gesamtumsatz/menge pro Ort/Kreis/Land/Region
Tag/Monat/Quartal/Jahr
Artikel/Artikelgruppe und -sparte
[Beispielabfrage 10]
drop materialized View Mav_Region_Zeit_Artikel_umsatz;
create MATERIALIZED VIEW Mav_Region_Zeit_Artikel_umsatz
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
ENABLE QUERY REWRITE
Document1
drop materialized view log on f_Bestellungen;
BUILD IMMEDIATE
BUILD DEFERRED
ON PREBUILD
Refresh Funktionen
COMPLETE
FAST
FORCE
NEVER
ON COMMIT
ON DEMAND
Feststellen, ob PCT Tracking funktioniert
select mview_name, num_PCT_TABLES from user_mviews;
Refresh auf eine MAV
EXECUTE dbms_mview.refresh('MV_standard_PCT_richtig','P');
P: PCT, (Partition Change Tracking, nur, wenn Partition
Schlüssel in der where-Klausel der MAV)
C: Complete (immer komplettes Refresh)
F: Fast (Inkrementelles Lesen, wenn möglich, View-Log oder PCT
?: Force, alle Varianten, die schnellste wird genommen
PMARKER Funktion
(Eingebaut ist DBMS_MVIEW.PMARKER(u.rowid) – Funktion um PCT
zu ermöglichen, wenn Partition Key Feld nicht in der WHEREKlausel der MAV enthalten ist.)
CREATE MATERIALIZED VIEW MV_standard_PCT_falsch_PM
ENABLE QUERY REWRITE AS SELECT
DBMS_MVIEW.PMARKER(u.rowid),
z.jahr_nummer Jahr,z.monat_desc Monat,
sum(u.umsatz) Summe,
a.artikel_id ID,
count(u.umsatz)
FROM f_umsatz_par u, d_artikel a, d_zeit z
WHERE a.artikel_id = u.artikel_id AND
u.zeit_id = z.datum_id
GROUP BY DBMS_MVIEW.PMARKER(u.rowid), z.jahr_nummer,
z.monat_desc, a.artikel_id;
Data Warehouse Technik im Fokus - Skripte in Kurzform
Komprimieren von Materialized Views
ALTER MATERIALIZED VIEW MV_standard COMPRESS;
EXECUTE
DBMS_MVIEW.REFRESH('MV_STANDARD',atomic_refresh=>TRUE);
EXECUTE dbms_stats.gather_table_stats('MAV','MV_standard');
SELECT table_name, tablespace_name, compression, BLOCKS
FROM user_tables;
Refresh auf alle von einer Tabelle abhängigen MAVs
(REFRESH DEPENDENT)
1.Beispiel
variable failures number;
EXECUTE DBMS_MVIEW.REFRESH_DEPENDENT(
:failures,'F_UMSATZ','C',refresh_after_errors=>true);
print failures
2. Beispiel
DBMS_MVIEW.REFRESH_DEPENDENT
('employees,deptartments,hr.regions','cf');
Aktualisieren aller Materialized Views
DBMS_MVIEW.REFRESH_ALL: -- hat keine Parameter
Anzeigen Materialized Views mit Zustand und View Logs
SELECT mview_name, update_log, stale_since, staleness
FROM user_mviews
Anzeigen Materialized Views mit Zustand und PCT Regions
SELECT mview_name, staleness, num_fresh_pct_regions,
num_stale_pct_regions
FROM user_mviews;
Stimmigkeit von Dimensionen prüfen
\ora-home\RDBMS\ADMIN\utldim.sql
DIMENSION_EXCEPTIONS an
 Legt Tabelle
variable stmt_id varchar2(30);
execute :stmt_id := 'CUST_DIM_VAL';
execute dbms_dimension.validate_dimension
('MAV.D_ARTIKEL',FALSE,TRUE,:stmt_id );
SELECT distinct owner, table_name, dimension_name,
relationship
FROM dimension_exceptions
WHERE statement_id = :stmt_id;
DBMS_MVIEW.Explain_mview
(Besser über Enterprise Manager analysieren)
start D:\O11\db11\RDBMS\ADMIN\utlxmv.sql
 Legt Tabelle mv_capabilities_table an
exec dbms_mview.explain_mview( 'SELECT z.jahr_nummer,z.monat_desc , sum(u.umsatz) ,a.artikel_id ID,count(u.umsatz) FROM f_umsatz_par u, d_artikel a, d_zeit z WHERE a.artikel_id = u.artikel_id AND u.bestell_datum = z.datum_desc GROUP BY z.jahr_nummer, z.monat_desc, a.artikel_id');
PL/SQL procedure successfully completed.
SELECT capability_name, possible p, substr(related_text,1,20)
obj, substr(msgtxt,1,100) erklaerung FROM
mv_capabilities_table;
Auflisten von Dimension-Tables
select dimension_name OWNER,DIMENSION_NAME,INVALID,
COMPILE_STATE,REVISION from user_dimensions
Anzeigen der Struktur einer Dimensional Table
EXECUTE DBMS_DIMENSION.DESCRIBE_DIMENSION('D_ARTIKEL');
Relevante Dictionary Views
ALL_MVIEWS
DBA_MVIEWS
USER_MVIEWS
USER_MVIEW_DETAIL_PARTITION
USER_MVIEW_DETAIL_RELATIONS
USER_MVIEW_DETAIL_SUBPARTITION
USER_DIMENSIONS
Document1
22 /41
Data Warehouse Technik im Fokus - Skripte in Kurzform
Optimierung für schnelles
Lesen
Optimizer - Statistiken sammeln
Statistiken für eine Tabelle
EXEC DBMS_STATS.GATHER_TABLE_STATS
('DWH','F_UMSATZ',estimate_percent=>100);
Statistiken für einen Index
EXEC DBMS_STATS.GATHER_INDEX_STATS
('DWH','PK_ARTIKEL',estimate_percent=>100);
Memory-Cache
Statistiken für eine Materialized View Definition
Tabellen in Cache legen / aus Cache entfernen
EXEC DBMS_STATS.GATHER_TABLE_STATS
('DWH','MAV_REGION_ZEIT_UMSATZ',estimate_percent=>100);
(Werden wie Tabellen behandelt)
alter table D_ARTIKEL cache;
alter table D_ARTIKEL nocache;
Statistiken für ein Schema
Welche Tabellen liegen im Cache
SELECT owner, table_name
= 'Y';
23 /41
FROM dba_tables
WHERE LTRIM(cache)
Query Result Cache
EXEC dbms_stats.gather_schema_stats(
ownname => 'ETLDB',
estimate_percent => 5,block_sample => TRUE)
Automatische Aktualisierung für ein Schema einrichten
begin
dbms_stats.gather_schema_stats(
ownname
=> 'PERF'
,options
=> 'GATHER AUTO'
,estimate_percent
=> 5
,block_sample
=> TRUE);
Aktivieren mit
alter system set result_cache_mode=FORCE; (MANUAL)
RESULT_CACHE_MAX_RESULT
RESULT_CACHE_MAX_SIZE
RESULT_CACHE_MODE
RESULT_CACHE_REMOTE_EXPIRATION
Ausnutzen Result Cache durch Hint in der Abfrage
SELECT /*+ result_cache */ COUNT(*), SUM(BESTELL_TOTAL)
FROM F_UMSATZ;
Abfragen auf im Cache befindliche Statements
end;
Automatisiertes Sampling
EXECUTE DBMS_STATS.GATHER_SCHEMA_STATS(
'OE',DBMS_STATS.AUTO_SAMPLE_SIZE);
Abfrage ob automatisiertes Sammel aktiviert ist
execute dbms_result_cache.memory_report()
SELECT client_name, status FROM dba_autotask_operation;
CLIENT_NAME
STATUS
-------------------------------------- -------auto optimizer stats collection
ENABLED
auto space advisor
ENABLED
sql tuning advisor
ENABLED
Result Cache leeren
Zustand/Aktualität der Statistiken abfragen
SELECT name, type, row_count, invalidations, scan_count
FROM v$result_cache_objects;
Result-Cache-Memory-Report
exec dbms_result_cache.flush;
Relvante Dictionary Views für Result-Cache
V$RESULT_CACHE_OBJECTS
Parallelisierung
select
table_name,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_ROW_LEN,SAMPLE_SIZ
E,LAST_ANALYZED ,STALE_STATS from user_tab_statistics;
Zustand von Index-Statistiken abfragen
select Index_name,TABLE_NAME,LAST_ANALYZED,STALE_STATS from
user_ind_statistics;
Histogramme abfragen
Relevante Fragestellungen
Aktivieren / Deaktivieren
Abfragen der eingestellten Parallelität
Gezieltes Steuern der Parallelität für einzelne Tabellen
Parallelisierung aktivieren
ALTER SESSION FORCE PARALLEL QUERY
ALTER SESSION ENABLE PARALLEL DML;
ALTER SESSION ENABLE PARALLEL DDL;
Automatisches Steuern mit
ALTER SESSION SET PARALLEL_AUTOMATIC_TUNING = TRUE; (veraltet)
Ab 11.2: ALTER SESSION/SYSTEM SET
PARALLEL_DEGREE_POLICY=MANUAL/LIMITD/AUTO
MANUAL: Kein automated DOP / Kein Statement Queuing /Kein InMemory Parallel Execution
LIMITED: Eingeschränkter automated DOP auf Tabellen mit
Default Parallelisierung , Kein In-Memory Parallel
Execution
AUTO: Alle Statements werden parallelisiert, Statement
Queuing / In-Memory Parallel Execution
Eine einzelne Tabelle auf parallel” setzen
ALTER TABLE tab_Name PARALLEL n;
ALTER TABLE tab_Name NOPARALLEL;
Parallelisierter Select-Zugriff
SELECT /*+ parallel(B) parallel(A) */ a,b,c FROM
BESTELLUNG B, ARTIKEL A;
INSERT /*+ APPEND PARALLEL(table_name)*/ INTO..
Prüfen welche Art der Parallelisierung eingestellt ist
select COLUMN_NAME,NUM_DISTINCT,NUM_BUCKETS,HISTOGRAM
from sys.USER_TAB_COL_Statistics
where TABLE_NAME ='BESTELLUNG'
Histogramme sammeln
begin
DBMS_STATS.GATHER_TABLE_STATS(Ownname=>'TIF',
Tabname=>'BESTELLUNG' ,
METHOD_OPT => 'FOR COLUMNS SIZE 10 KUNDENCODE');
end;
Abfragen der Grenzwerte der Histogram-Buckets
SELECT
ENDPOINT_NUMBER, ENDPOINT_VALUE
FROM
USER_TAB_HISTOGRAMS
WHERE
TABLE_NAME = 'F_UMSATZ' and COLUMN_NAME =
'ARTIKEL_ID' order by ENDPOINT_NUMBER
Löschen von Statistiken
BEGIN
DBMS_STATS.DELETE_table_STATS (
OWNNAME
=> 'DWH',
TABNAME
=> 'D_ARTIKEL');
END;
Löschen von Histogrammen für einzelne Spalten
BEGIN
dbms_stats.delete_column_stats(
ownname=>'DWH', tabname=>'F_UMSATZ',
colname=>'ARTIKEL_ID', col_stat_type=>'HISTOGRAM');
END;
Markieren von Tabellen um inkrementelles Aktualisieren zu ermöglichen
Exec DBMS_STATS.SET_TABLE_PREFS(<OWNER>, <TABLE_NAME>,
'INCREMENTAL', ‘TRUE’);
select userName,PDML_ENABLED,PDML_STATUS,PDDL_STATUS,PQ_STATUS
from v$session;
exec DBMS_STATS.SET_TABLE_PREFS('DWH','F_UMSATZ',
'INCREMENTAL', 'TRUE');
Aktuelle SQL-Statements und deren Parallelisierung abfragen
Relvante Dictionary Views für Statistiken
select status, username, to_date(SQL_EXEC_START,'DD-MON-YY') ,
PX_SERVERS_REQUESTED PX_Req, PX_SERVERS_ALLOCATED
PX_Alc,substr(sql_text,1,20) from V$SQL_MONITOR where username
= 'DWH';
(wird erst nach 5 Sekunden Laufzeit aktiviert)
Relevante Dictionary Views für Parallelisierung
v$session
v$sql_monitor

SQL-Monitor im Enterprise Manger nutzen
Document1
USER_TAB_STATISTICS
USER_TAB_COL_STATISTICS
USER_IND_STATISTICS
USER_HISTOGRAMS
USER_TAB_HISTOGRAMS
Data Warehouse Technik im Fokus - Skripte in Kurzform
24 /41
Logins pro User
Umgebungsinformationen
auslesen
Datenbank-Informationen, Version, Patchstände
Relevante Fragestellungen
DB-Namen
Version
Patchstände
Installierte Komponenten
Database-ID abfragen
select dbid from v$database;
DBID
---------1053456982
Installierte Komponenten
select comp_id,substr(comp_name,1,30) Name ,version,status
from dba_registry;
Patchstand abfragen
Auf der Betriebssystemebene mit
Opatch lsinventory –detail
(Opatch befindet sic him Oracle – Home Verzeichnis
Patch-Historie
select username,count(1) from v$session group by username
User Platzverbrauch Tablespace
set heading on
set pagesize 200
set newpage 0
set line 200
SELECT T1.USERNAME, T2.TABLESPACE, T2.CONTENTS, T2.EXTENTS,
T2.BLOCKS
FROM V$SESSION T1, V$SORT_USAGE T2
WHERE T1.SADDR = T2.SESSION_ADDR ;
Maximale Parallelität von Benutzeraktivitäten
select username, sid, process_name, sql_id,
px_maxdop,PX_SERVERS_REQUESTED, substr(sql_text,1,80) from
v$sql_monitor where username = 'PETER';
USERNAME
SID PROCE SQL_ID
PX_MAXDOP
PX_SERVERS_REQUESTED SUBSTR(SQL_TEXT,1,80)
--------------------------------------------------------------------------------------------------------------------PETER
191 ora
apzgjdwwcxb2j 8
16 select
distinct vertriebskanal from mon.BESTELLUNG_PART_RANGE_4
Relevante Dictionary Views
V$SESSION
DBA_USERS
v$sql_monitor
Tablespaces, Auflistungen, Mengen und Größen
SELECT * FROM sys.registry$history
Datenbankversion abfragen
SELECT * FROM v$version
Relevante Dictionary Views
dba_registry
V$version
V$SESSION
V$DATABASE
User-Informationen / Einstellungen /Security
Welche USER gibt es in einer Umgebung und welchen Zustand haben sie
select username, account_status, lock_date from dba_users
order by username;
Benutzer anlegen
Create user DWH identified by DWH default tablespace users;
GRANT create session to DWH;
Create user OLTP identified by OLTP default tablespace users;
GRANT create session to OLTP;
Eigene Tabellen zum Lesen für alle freigeben
Grant select any table to public;
Allgemeine Benutzerinformationen abfragen
Relevante Fragestellungen
Welche Tabellen belegen den meisten Platz?
Wo lohnt sich das „Platzsparen“?
Wieviel freien Platz hat die Datenbank noch?
Definition von Tablespaces für performantes Massenladen?
Anlegen eines Tablespace mit Zuweisung eines Datafiles
CREATE SMALLFILE TABLESPACE "TS_DWH" DATAFILE
'D:\APP\ORADATA\ORCL\DF_DWH'
SIZE 10G LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE
MANAGEMENT AUTO
Größe aller Data Files
select sum(bytes)/1024/1024 Meg from dba_data_files;
Liste aller Tablespace mit Größenangaben
select substr (tablespace_name, 1, 15)
"tablespace",
substr (file_name, 1, 33) "Datei",
bytes,
blocks,
status,
autoextensible,
maxbytes,
maxblocks,
increment_by
from dba_data_files
order by tablespace_name, file_name;
SQL> desc dba_Users
Temp-Space
select s.user#, u.user_ID, s.USERNAME,u. PROFILE ,
u.DEFAULT_TABLESPACE, substr(s.PROGRAM,1,30) Programm,
s.Module
from v$session s,dba_users u
where
s.user# = u.user_ID
and s.user# != 0
/
select nvl(sum(bytes),0)/1024/1024 Meg from dba_temp_files;
Ausschalten Expiration Date in Entwicklungs- und Test-Umgebung
select table_name, Blocks from user_tables
order by blocks desc
ALTER PROFILE DEFAULT LIMIT
FAILED_LOGIN_ATTEMPTS UNLIMITED
PASSWORD_LIFE_TIME UNLIMITED;
Ändern des Lock-Zustads eines Users
alter user ANONYMOUS account UNLOCK;
Welche Rechte wurden einem User vergeben
-- Beispiel DWH
SELECT PRIVILEGE
FROM sys.dba_sys_privs
WHERE grantee = 'DWH'
UNION
SELECT PRIVILEGE
FROM dba_role_privs rp JOIN role_sys_privs rsp ON
(rp.granted_role = rsp.role)
WHERE rp.grantee = 'DWH'
ORDER BY 1
Plattenplatz der Segment-Objekte eines Users
column segment_name format a30
SELECT sg.segment_name, sg.SEGMENT_TYPE, sg.extents,
sg.tablespace_name,
sg.blocks, ts.BLOCK_SIZE,
round((sg.blocks*ts.BLOCK_SIZE)/1000000,2) MB_SIZE
FROM dba_segments sg, dba_tablespaces ts
WHERE
owner = 'PERF' and
ts.TABLESPACE_NAME = sg.TABLESPACE_NAME
Document1
Größe Redo Logs
select sum(bytes)/1024/1024 Meg from sys.v_$log;
Finden der größten Tabellen
select table_name, Owner, blocks from dba_tables
where owner = 'MON' order by blocks
Top 10 größten Tabellen eines Users
where rownum < 10
Data Files + Redo Logs + Temp
select a.data_size+b.temp_size+c.redo_size total_size
from ( select sum(bytes) data_size
from dba_data_files ) a,
( select nvl(sum(bytes),0) temp_size
from dba_temp_files ) b,
( select sum(bytes) redo_size
from sys.v_$log ) c;
Freier Datenbank-Platz
-- freespace report
col Database Size format a20
col Free space format a20
select round(sum(used.bytes) / 1024 / 1024 ) || ' MB' Database
Size
,
round(free.p / 1024 / 1024) || ' MB' Free space
from (select bytes from v$datafile
union all
select bytes from v$tempfile
union all
select bytes from v$log) used
,
(select sum(bytes) as p from dba_free_space) free
group by free.p
/
Benutzter Datenbank-Platz
SELECT SUM(bytes)/1024/1024 Meg FROM dba_segments;
Data Warehouse Technik im Fokus - Skripte in Kurzform
Belegter und benutzter Temp-Tablespace
SELECT
column size_mb heading '&&this_mon' format 99999 column
size_mb2 heading '&&prev_mon' format 99999 column size_mb1
heading '&&last_mon' format 99999
column growth heading 'Growth(%)| in |last month' format
9999.99
SELECT tablespace_name,
-- to_char(snap_time, 'MON YYYY') month
MAX(decode(trunc(snap_time, 'MON'), trunc(add_months(SYSDATE,
-2), 'MON'),size_m,0)) size_mb2,
MAX(decode(trunc(snap_time, 'MON'), trunc(add_months(SYSDATE,
-1), 'MON'),size_m,0)) size_mb1,
MAX(decode(trunc(snap_time, 'MON'),
trunc(SYSDATE,'MON'),size_m,0)) size_mb,
100*(MAX(decode(trunc(snap_time, 'MON') ,trunc(SYSDATE,
'MON'), size_m, 0))
- MAX(decode(trunc(snap_time, 'MON'),
trunc(add_months(SYSDATE, -1), 'MON'), size_m, 0)))
/MAX(decode(trunc(snap_time, 'MON'),
trunc(add_months(SYSDATE, -1), 'MON'), size_m, 1)) growth
FROM (SELECT tablespace_name, snap_time, sum(bytes)/1024/1024
size_M
FROM stats$segment_info
WHERE snap_time > trunc(add_months(SYSDATE, -2), 'MON')-2
GROUP BY tablespace_name, snap_time) A
GROUP BY tablespace_name;
--ORDER BY tablespace_name;
A.tablespace_name tablespace, D.mb_total,
SUM (A.used_blocks * D.block_size) / 1024 / 1024
mb_used,
D.mb_total - SUM (A.used_blocks * D.block_size) /
1024 / 1024 mb_free
FROM
v$sort_segment A,
(
SELECT
B.name, C.block_size,
SUM (C.bytes) / 1024 / 1024 mb_total
FROM
v$tablespace B, v$tempfile C
WHERE
B.ts#= C.ts#
GROUP BY B.name, C.block_size
) D
WHERE
A.tablespace_name = D.name
GROUP by A.tablespace_name, D.mb_total;
Blockgrößen auslesen
select tablespace_name, block_size from dba_tablespaces;
TABLESPACE_NAME
BLOCK_SIZE
------------------------------ ---------SYSTEM
8192
SYSAUX
8192
UNDOTBS1
8192
TEMP
8192
USERS
8192
EXAMPLE
8192
MON_G
8192
MON
8192
MON_D
8192
MON_E
8192
MON_F
8192
Liste Tabellen und Berechnung der Größe in Byte, MB, GB
SELECT table_name, num_rows, blocks,
blocks*8 KB,blocks*8/1000 MB,blocks*8/1000000 GB
FROM user_tables;
TABLE_NAME
NUM_ROWS
BLOCKS
KB
------------------------------------- ---------- ---------BESTELLUNG_PART_RANGE
163840000
962355
7698840
BESTELLUNG_PART_RANGE_4
163840000
962355
7698840
Tabellengrößen und Platzverbrauch
SELECT table_name, num_rows, blocks, blocks*8 KB,
blocks*8/1000 MB,blocks*8/1000000 GB
FROM user_tables;
TABLE_NAME
-----------------------BESTELLUNG_PART_RANGE
BESTELLUNG_PART_RANGE_4
25 /41
NUM_ROWS
BLOCKS
KB
MB
GB
---------- ---------- ---------- ---------163840000 962355
7698840 7698,84 7,69884
163840000 962355
7698840 7698,84 7,69884
Größen und Mengen mit zusätzlichem Tablespace-Namen
Growth(%) in
--TABLESPACE_NAME
---- -----------DWH1
--EXAMPLE
--PERFSTAT
--SYSAUX
--SYSTEM
--TEST_ALERT
--UNDOTBS1
--USERS
BREAK ON report
COMPUTE SUM OF filesize
COMPUTE SUM OF used
COMPUTE AVG OF pct_used
SEGMENT_NAME
PARTITION_NAME
SEGMENT_TYPE
TABLESPACE_NAME
EXTENTS
---- -------------------- ---------- ---------- ---------BESTELLUNG_PART_RANGE
APR10
TABLE PARTITION
MON
123
53248
BESTELLUNG_PART_RANGE
APR11
TABLE PARTITION
MON
132
62464
BESTELLUNG_PART_RANGE
AUG10
TABLE PARTITION
MON
137
67584
BLOCKS KB
425984
499712
540672
Auflisten des Wachstums einzelner Tablespaces
CREATE TABLE stats$segment_info AS
SELECT SYSDATE snap_time,owner, segment_name,segment_type,
tablespace_name, sum(bytes) bytes
FROM dba_segments
GROUP BY SYSDATE, owner, segment_name, segment_type,
tablespace_name;
INSERT INTO stats$segment_info
SELECT SYSDATE snap_time, owner, segment_name,segment_type,
tablespace_name, sum(bytes) bytes
FROM dba_segments
GROUP BY SYSDATE, owner, segment_name, segment_type,
tablespace_name;
column this_mon new_value this_mon
column last_mon new_value last_mon
column prev_mon new_value prev_mon
SELECT to_char(SYSDATE,'MON YYYY') this_mon,
to_char(add_months(SYSDATE,-1),'MON YYYY') last_mon,
to_char(add_months(SYSDATE,-2),'MON YYYY') prev_mon FROM
dual;
column mins format 99999
Document1
SIZE_MB last month
73.3125
77.4375
96.75
616.3125
694.0625
3
21.25
3.125
7331.25
7743.75
9675.00
########
########
300.00
2125.00
312.50
Gesamtauswertung belegter Plattenplatz und Freespace pro Tablespace
und Datafiles
Welche Objekte gehören zu einem Tablespace
column segment_name format a25
column partition_name format a20
column tablespace_name format a20
SELECT segment_name, partition_name, segment_type,
tablespace_name, extents, blocks, bytes/1024 KB
FROM user_segments WHERE segment_name =
'BESTELLUNG_PART_RANGE';
0
0
0
0
0
0
0
0
SQL> select distinct segment_type from user_segments;
SEGMENT_TYPE
-----------------TABLE SUBPARTITION
TABLE PARTITION
TABLE
INDEX
SET LINESIZE 145
SET PAGESIZE 9999
SET VERIFY
OFF
Größenangaben bezogen auf Partitionen
SIZE_MB1
0
0
0
0
0
0
0
0
Segment-Informationen
select table_name, tablespace_name, num_rows, blocks, blocks*8
KB, blocks*8/1000 MB,blocks*8/1000000 GB
FROM user_tables;
SELECT table_name, tablespace_name, partitioned, num_rows,
compression, compress_for, blocks, blocks*8 KB FROM
user_tables;
SELECT table_name, def_tablespace_name, partitioning_type,
subpartitioning_type, partition_count, status FROM
user_part_tables;
SELECT partition_name, partition_position, num_rows, blocks,
tablespace_name, high_value
FROM user_tab_partitions WHERE table_name =
'BESTELLUNG_PART_RANGE';
select owner,segment_name,segment_type, Blocks, bytes/1000000
MB from dba_segments where tablespace_name='DWH_SPINDEL'
SIZE_MB2
COLUMN tablespace
COLUMN filename
COLUMN filesize
Size'
COLUMN used FORMAT
bytes)'
COLUMN pct_used
FORMAT a18
HEADING 'Tablespace Name'
FORMAT a50
HEADING 'Filename'
FORMAT 999.999,999,999,999 HEADING 'File
999.999,999,999,999 HEADING 'Used (in
FORMAT 999
HEADING 'Pct. Used'
ON report
ON report
ON report
SELECT /*+ ordered */
d.tablespace_name
tablespace
, d.file_name
filename
, d.file_id
file_id
, d.bytes
filesize
, NVL((d.bytes - s.bytes), d.bytes)
used
, TRUNC(((NVL((d.bytes - s.bytes) , d.bytes)) / d.bytes) *
100) pct_used
FROM
sys.dba_data_files d
, v$datafile v
, ( select file_id, SUM(bytes) bytes
from sys.dba_free_space
GROUP BY file_id) s
WHERE
(s.file_id (+)= d.file_id)
AND (d.file_name = v.name)
UNION
SELECT
d.tablespace_name
tablespace
, d.file_name
filename
, d.file_id
file_id
, d.bytes
filesize
, NVL(t.bytes_cached, 0)
used
, TRUNC((t.bytes_cached / d.bytes) * 100) pct_used
FROM
sys.dba_temp_files d
, v$temp_extent_pool t
, v$tempfile v
WHERE
(t.file_id (+)= d.file_id)
AND (d.file_id = v.file#)
/
Relevante Dictionary Views
V$TABLESPACE
V$DATAFILE
V$TEMPFILE
DBA_SEGMENTS
Data Warehouse Technik im Fokus - Skripte in Kurzform
DBA_TABLES
DBA_FREE_SPACE
V$TEMP_EXTENT_POOL
V$LOG
DBA_TEMP_FILES
V$TEMPFILE
Database Files
Auffinden der Datafiles in denen die DWH-Tabellen liegen.
Ein Data File soll gelöscht werden, man weiss aber nicht,
welche Tabellen dort „vergraben“ sind.
Auflistung aller Dateien
from dba_data_files;
In welchen Datafiles liegen bestimmte Tabellen
column segment_name format a20
column owner
format a10
column file_name format a50
select
e.owner,
e.segment_name,
e.file_id,
d.file_name
from
dba_extents e,
dba_data_files d
where
e. owner = 'DWH' and
e.segment_type = 'TABLE' and
e.segment_name = 'BESTELLUNG' and
e.file_id = d.file_id
order by e.file_id;
Welche Tabellen liegen in einem bestimmten Data File
[die File ID mit obigem Kommando herausfinden und unten
eintragen]
select
e.owner,
e.segment_name,
e.file_id,
d.file_name
from
dba_extents e,
dba_data_files d
where
e. owner = 'DWH' and
e.segment_type = 'TABLE' and
d.file_id = 7 and
e.file_id = d.file_id
order by e.segment_name;
Single Block / Multi Block Reads
SELECT f.FILE_NAME datei,
v.SINGLEBLKRDS,
v.PHYRDS - v.SINGLEBLKRDS Multi
FROM v$filestat v, dba_data_files f
WHERE v.FILE# = f.file_id;
Database Files mit asynchronem Lesen und Schreiben
col name format a50
SELECT name, asynch_io FROM v$datafile f,v$iostat_file i
WHERE f.file#
= i.file_no
AND
filetype_name = 'Data File'
/
NAME
ASYNCH_IO
------------------------------------------ --------D:\ORA\ORADATA\O112\SYSTEM01.DBF
ASYNC_ON
D:\ORA\ORADATA\O112\SYSAUX01.DBF
ASYNC_ON
D:\ORA\ORADATA\O112\UNDOTBS01.DBF
ASYNC_ON
D:\ORA\ORADATA\O112\USERS01.DBF
ASYNC_ON
D:\ORA\ORADATA\O112\EXAMPLE01.DBF
ASYNC_ON
G:\ORADATA\MON_X.DBF
ASYNC_ON
G:\ORADATA\MON.DBF
ASYNC_ON
G:\ORADATA\MON2
ASYNC_ON
G:\ORADATA\MON3
ASYNC_ON
G:\ORADATA\MON4
ASYNC_ON
Relevante Dictionary Views
dba_data_files
dba_extents
Lesestatistiken / Benutzungsverhalten
Gelesene und geschriebene Blöcke
select substr (name, 1, 40) "Datei",
phyblkrd "Blk Lesen",
phyblkwrt "Blk Schreiben",
phyblkrd + phyblkwrt "BlK Gesamt"
from v$datafile df, v$filestat fs
where df.file# = fs.file#
order by phyblkrd + phyblkwrt desc;
Datei
Blk Lesen Blk Schreiben BlK Gesamt
--------------------------------------------- ------------- ---------F:\ORA_DATA\DWHTIF
3441934
83362
3525296
E:\APP\ORADATA\ORCL\SYSAUX01.DBF
51449
45799
97248
E:\APP\ORADATA\ORCL\SYSTEM01.DBF
36970
4476
41446
E:\APP\ORADATA\ORCL\USERS01.DBF
15206
7886
23092
E:\APP\ORADATA\ORCL\DWH_SSD
12577
4955
17532
E:\APP\ORADATA\ORCL\UNDOTBS01.DBF
55
17234
17289
E:\APP\ORADATA\ORCL\EXAMPLE
3728
2284
6012
F:\ORA_DATA\DWH_SPINDEL
27
9
36
Document1
E:\APP\ORADATA\ORCL\T1
17
9
Security
Benutzer anlagen
Relevante Fragestellungen
select file_name,file_id
26 /41
Create user XXX identified by XXX [Default tablespace TSname];
Drop user XXX [CASCADE]
Ein Profil anlegen
create profile pr_develop limit
password_reuse_max 10
password_reuse_time 30
sessions_per_user unlimited
cpu_per_session unlimited
cpu_per_call 3000
connect_time 45
;
Eine Rolle anlegen
create role DWH_ACCESS;
grant select on DWH.F_UMSATZ to DWH_ACCESS;
grant select, delete on DWH_ACCESS;
grant execute on proc_ABC to DWH_ACCESS;
Rollenrechte weitergeben
GRANT DWH_ACCESS to user_name;
Default-Rolle einem Benutzer zuweisen
alter user user_name default role DWH_ACCESS;
Rollen für einen Bnutzer aktivieren / deaktivieren
set role r01, r02, r03;
set role all;
set role none;
Was machen die Benutzer gerade
select EXECUTIONS, USERS_EXECUTING, username, sql_text
from v$session se , v$sql sq
where se.sql_address = sq.address;
Relevante Dictionary Views
Objektrechte
all_tab_privs
user_tab_privs
dba_tab_privs
all_col_privs
user_col_privs
dba_col_privs
Systemrechte
user_sys_privs
dba_sys_privs
session_privs
Weitergegebene Rechte
all_tab_privs_made
user_tab_privs_made
all_col_privs_made
user_col_privs_made
Erhaltene Rechte
all_tab_privs_recd
user_tab_privs_recd
all_col_privs_recd
user_col_privs_made
Quotas
user_ts_quotas
all_ts_quotas
dba_ts_quotas
User
user_users
all_users
dba_users
Rollen
role_sys_privs
role_tab_privs
role_role_privs
26
Data Warehouse Technik im Fokus - Skripte in Kurzform
Laden des DWH
Relevante Fragestellungen
Datenbank-basiertes Laden
Datenbank-Techniken für den ETL Prozess
Mengen-basiertes Laden
Arbeiten mit und ohne Constraints
Datenprüfungen mit Native-SQL
Bewegen großer Datenmengen
Komplexe Logik bei hoher Performance
Schnelles Laden / Mengenbasiertes Laden
Grunsätzliches Schema für mengenbasiertes Laden
Insert into TARGET_TABLE select * from SOURCE_TABLE;
Direct Path Load
Es gibt 4 Möglichkeiten einen Direct Path zu erzeugen:
Insert /*+ APPEND */ into TARGET_TABLE select * from
SOURCE_TABLE;
[CTAS]
Create table NEW_TABLE as select * from SOURCE_TABLE;
SQL LOADER
-> DIRECT=TRUE
-> Schlüsselwort.
External Table -> DIRECT=TRUE
-> Schlüsselwort.
Insert /*+ NOLOG */ into zieltabelle select .....,
(Der Hint wird von der DB akzeptiert, ist aber ohne Wirkung.
Soll ohne Log-Datei geladen werden, dann muss man entweder den
Direct Path Load nutzen, oder die DB im norarchive-Log-Mode
betreiben.)
Sequence-Objekt anlegen
CREATE SEQUENCE Kun_seq
INCREMENT BY 1 START WITH 1;
Insert into … select Kun_seq.NEXTVAL from dual
Schnelles Schreiben CTAS (Create Table As Select)
Create table f_umsatz_tmp as select * from F_Umsatz;
Schnelles Löschen von Daten
(Möglichst Einzel-Deletes umgehen)
Truncate table f_umsatz_tmp;
Drop table f_umsatz_tmp;
(Möglichst mit Partition Exchange arbeiten. Dann lassen sich
Lösch-Operationen auf Partition-Ebene durchführen und sind
schneller)
Drop Partition ....
Text-Dateien Importieren
SQL Loader
sqlldr userid=DWH/DWH control=c:\orte.ctl log=C:\orte.log
Beispiel für Loader Control – File
-> orte.ctl ->
OPTIONS (SKIP=1, BINDSIZE=50000, ERRORS=50, ROWS=200,
DIRECT=TRUE,
PARALLEL=TRUE, READSIZE=65536, RESUMABLE=TRUE,
RESUMABLE_TIMEOUT=7200)
UNRECOVERABLE LOAD DATA
CHARACTERSET WE8MSWIN1252
INFILE 'C:\orte.csv'
BADFILE 'orte.bad'
DISCARDFILE 'orte.dis‚
INTO TABLE dwh.tb_orte WHEN ort_id != BLANKS
APPEND
REENABLE DISABLED_CONSTRAINTS
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY "'"
(orte_nr POSITION(1) INTEGER EXTERNAL ,
ort CHAR ,
plz CHAR ,
bundesland CHAR ,
region CHAR ,
nummernfeld INTEGER EXTERNAL )
CREATE TABLE Gemeinde_EX (
Gemeinde_Nr
VARCHAR2(8),
Gemeinde
VARCHAR2(50) )
ORGANIZATION EXTERNAL
(TYPE oracle_loader
DEFAULT DIRECTORY Exttab
ACCESS PARAMETERS
(RECORDS DELIMITED BY newline
BADFILE 'Gemeinde.bad‚
DISCARDFILE 'Gemeinde.dis‚
LOGFILE 'Gemeinde.log‚
SKIP 20
FIELDS TERMINATED BY ;
OPTIONALLY ENCLOSED BY '‚
)
LOCATION ('Gemeinde_CSV.TXT'))
Directory-Objekte
Directory anlegen
CREATE DIRECTORY Exttab AS 'D:\Szenario\Exttab';
Auflisten bestehender Directory-Definitionen
Databas Link
Zugriff auf Remote-Oracle-Datenbank (Database Link)
CONNECT TO "DWH"
Verwendung
Select * from SOURCE_TABLEqDWH;
Sequence für Zähl-Felder / Schlüssel aufbauen
Defintion eines Sequence-Objektes
create sequence kd_seq increment by 1 start with 1;
Zugriff um den nächsten Zählerwert abzugreifen
select seq_kd.nextval from dual;
Abfragen des aktuellen Stands
select LAST_NUMBER from user_sequences where sequence_name =
'SEQ_KD'
Relevante Dictionary Views
user_sequences
Trigger
Einsatz in den Source- (OLTP) – Systemen zum erkennen von
Delta-Daten. Kann die Quell-Systeme belasten.
Beispiel für einen Trigger (Insert,Delete,Update)
CREATE OR REPLACE TRIGGER Bestellung
BEFORE DELETE OR INSERT OR UPDATE ON Bestellung
FOR EACH ROW
WHEN (new.Bestellnr > 0)
DECLARE
sal_diff number;
BEGIN
INSERT INTO log_Bestellung
(Alte_Bestell_Nr,Neue_Bstell_Nr)
Document1
VALUES(old.Bestellnr,new.Bestellnr);
END;
External Table Beispiel
Insert ohne Log-Datei
CREATE DATABASE LINK "DWH"
IDENTIFIED BY "DWH"
USING 'ORA10' ;
27 /41
select substr(owner,1,15),
substr(DIRECTORY_NAME,1,20),substr(DIRECTORY_PATH,1,30) from
dba_directories;
Logischen Directory-Name ändern
alter table ex_orte default directory LC_Texte_2;
Name der Daten-(CSV-)Datei ändern
alter table ex_orte location ('ORTE_Y.CSV');
Datapump
Datapump - Beispiel mit Steuerdatei
expdp dwh/dwh@o11 parfile=Para_EX.txt
-> Datei Para_EX kann die Parameter haben:
SCHEMAS=(DWH)
INCLUDE=TABLE IN ('BESTELLUNG')
QUERY=BESTELLUNG:WHERE BESTELLDATUM >
to_date('01.08.06','DD.MM.YY')
DIRECTORY=DP_OUT
DUMPFILE=EXP1.dmp
LOGFILE=DP_OUT:EXP_LOG.dmp
impdp dwh2/dwh2@o11 DIRECTORY=DP_OUT
DUMPFILE=EXP1.DMP
LOGFILE=DP_OUT:imp_log
REMAP_SCHEMA=DWH:DWH2
Allgemeines Beispiel
Expdp hf TABLES=employees,jobs DUMPFILE=dpump_dir1:Table.dmp
NOLOGFILE=y
Umändern des Default-Output-Directories
CREATE OR REPLACE DIRECTORY expimp_dir AS 'H:\';
Danach Angabe des so definierten DIRECTORIE über den
DIRECTORY-Parameter in dem EXPDP – Aufruf.
Datapump-Schätzung benötigter Plattenplatz
Expdp hr DIRECTORY=dpump_dir1 ESTIMATE_ONLY=y
TABLES=employees, departments, locations LOGFILE=estimate.log
Data Warehouse Technik im Fokus - Skripte in Kurzform
28 /41
Datapump Data only Import
Impdp hr TABLES=employees CONTENT=DATA_ONLY DUMPFILE=
dpump_dir1:Table.dmp NOLOGFILE=y
Datapump Schema Mode
Impdp hr SCHEMAS=hr DIRECTORY=dpump_dir1
DUMPFILE=expschema.dmp EXCLUDE=CONSTRAINT,REF_CONSTRAINT,INDEX
TABLE_EXISTS_ACTION=REPLACE
Datapump Network Mode
Impdp hr TABLES=employees REMAP_SCHEMA=hr:scott
DIRECTORY=dpump_dir1 NETWORK_LINK=dblink
Interaktiver Modus mit CTRL C aktivierbar
Befehl
Beschreibung
------------------------------------------------------------ADD_FILE
CONTINUE_CLIENT
gestartet, wenn
EXIT_CLIENT
FILESIZE
Befehle.
HELP
KILL_JOB
PARALLEL
Job.
Fügt Dump-Datei zu Dump-Dateigruppe hinzu.
Kehrt in den Logging-Modus zurück. Job wird neu
frei.
Beendet Client-Session, Job wird weiter ausgeführt.
Standarddateigröße (Byte) für nachfolgende ADD_FILEFasst interaktive Befehle zusammen.
Hebt Zuordnung von Job auf und löscht Job.
Ändert die Anzahl von aktiven Workern für den aktuellen
PARALLEL=<number of workers>.
REUSE_DUMPFILES überschreibt Ziel-Dump-Datei sofern vorhanden (N).
START_JOB
Startet/nimmt aktuellen Job wieder auf.
STATUS
Gibt an, wie oft (in Sekunden) der Job-Status überwacht
werden soll, wobei
der Standardwert (0) den neuen Status anzeigt, wenn
verfügbar.
STATUS[=interval]
STOP_JOB
Fährt die Job-Ausführung ordnungsgemäß herunter und
beendet den Client.
STOP_JOB=IMMEDIATE nimmt ein sofortiges Herunterfahren
des
Data Pump Jobs vor.
Datapump und External Tables
-- In Quellumgebung:
CREATE TABLE ex_bestellung
ORGANIZATION EXTERNAL
(
TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY dp_out
LOCATION ('best.dmp')
)
AS SELECT * FROM bestellung;
-- In Zielumgebung
CREATE TABLE ex_bestellung_2
(
BESTELLNR
NUMBER,
KUNDENCODE
NUMBER,
BESTELLDATUM
DATE,
LIEFERDATUM
DATE,
BESTELL_TOTAL
NUMBER(12,2),
ORDER_ID
NUMBER)
ORGANIZATION EXTERNAL
(TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY DP_OUT
LOCATION ('best.dmp'))
REJECT LIMIT UNLIMITED;
-- In Zielumgebung
CREATE TABLE ex_bestellung_3
ORGANIZATION EXTERNAL
(
TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY DP_OUT
LOCATION ('best.dmp')
)
REJECT LIMIT UNLIMITED;
Transportable Tablespace
Transportable Tablespace-Verfahren
--- 1. Erstellen Tablespace
CREATE TABLESPACE ts_bestellung DATAFILE
'D:\oracle\oradata\dworcl\TS_BEST.tbs' SIZE 100M REUSE
AUTOEXTEND ON NEXT 10M;
--- 2. Zuweisen von tabelendaten zum Tablespace
CREATE TABLE ts_best TABLESPACE ts_bestellung AS SELECT * FROM
bestellung ;
--- 3. Setzen des Tablespace auf Read Only ALTER TABLESPACE
ts_bestellung READ ONLY;
--- 4. Export Metadaten des Tablespace
CREATE OR REPLACE DIRECTORY ts_dir AS 'D:\Workshop\TS_DIR';
expdp sys/****@orcldw TRANSPORT_TABLESPACES=ts_bestellung
DIRECTORY=ts_dir DUMPFILE=ts_best_file
--- 5. Konvertieren der Metadaten
RMAN:
CONVERT TABLESPACE ts_bestellung TO PLATFORM 'Microsoft
Windows IA (32-bit)' FORMAT '......
;
---- 6. Kopieren der TS-Datei und der Metadaten
---- 7. Import
impdp system/****@orcldw TRANSPORT_TABLESPACES=ts_bestellung
DIRECTORY=ts_dir DUMPFILE=ts_best_file
Document1
Error Logging
Error Logging
Eine Tabelle Errorlog-fähig machen
BEGIN
DBMS_ERRLOG.CREATE_ERROR_LOG(
dml_table_name
=> 'EL_KUNDE',
-- required
err_log_table_name => 'EL_KUNDE_ERRORS' --optional
);
END;
/
Es entstehen zusätzliche Spalten, die das System bei
Constraint-Verletzungen pflegt:
SQL> desc el_kunde_errors
Name
Null?
Typ
----------------------- -------- -------------------ORA_ERR_NUMBER$
NUMBER
ORA_ERR_MESG$
VARCHAR2(2000)
ORA_ERR_ROWID$
ROWID
ORA_ERR_OPTYP$
VARCHAR2(2)
ORA_ERR_TAG$
VARCHAR2(2000)
KUNDENNR
VARCHAR2(4000)
VORNAME
VARCHAR2(4000)
NACHNAME
VARCHAR2(4000)
ORTNR
VARCHAR2(4000)
STRASSE
VARCHAR2(4000)
TELEFON
VARCHAR2(4000)
Eindeutigkeitsprüfung ohne DML_Error_Logging
-- Quelltabelle mit 1000003 Millionen Sätzen davon 3 mit
-- doppelter Kundennr aufbauen:
drop table kd_xx;
create table kd_xx as
select
to_number(substr(level,1,10)) kundennr,'a' Vorname,'a'
nachname,1 ortnr,'a' Str,'q' Tel
from dual connect by level < 1000001;
-- nicht eindeutige Sätze einfügen
insert into kd_XX (kundennr) values(74);
insert into kd_XX (kundennr) values(784);
insert into kd_XX (kundennr) values(7874);
-- Nicht eindeutige Werte heraussuchen
Drop table non_uni
/
Create table non_uni as
select distinct kundennr from
(select count(*) c, kundennr from kd_xx group by kundennr)
where c > 1
/
-- Nur die Sätze in eine weitere Zieltabelle überführen, die
eindeutig sind
insert into el_kunde
select * from kd_xx where kundennr not in (select * from
non_uni);
Regular Expressions
Regular Expression in Constraints verwenden
ALTER TABLE check_kunde
ADD CONSTRAINT Ch_KD_Name
CHECK(REGEXP_LIKE(NACHNAME, '[^[:digit:]]'));
Umgang mit einzelnen Zeichen:
* Match 0 or more times
? Match 0 or 1 time
+ Match 1 or more times
{m} Match exactly m times
{m,} Match at least m times
{m, n} Match at least m times but no more than n times
\n Cause the previous expression to be repeated n times
Bestehende Zeichengruppen
[:alnum:] Alphanumeric characters
[:alpha:] Alphabetic characters
[:blank:] Blank Space Characters
[:cntrl:] Control characters (nonprinting)
[:digit:] Numeric digits
[:graph:] Any [:punct:], [:upper:], [:lower:], and [:digit:]
chars
[:lower:] Lowercase alphabetic characters
[:print:] Printable characters
[:punct:] Punctuation characters
[:space:] Space characters (nonprinting), such as carriage
return, newline,
vertical tab, and form feed
[:upper:] Uppercase alphabetic characters
[:xdigit:] Hexidecimal characters
Data Warehouse Technik im Fokus - Skripte in Kurzform
Arbeiten ohne Constraints und mengenbasiertes
SQL / Prüfen
Gemeint ist das Prüfen von zu ladenden Daten ohne DatenabnkConstraints, um die Performance zu erhöhen. Prüfungen lassen
sich nach Typen kategorisieren (Siehe Graphik unten). Für die
einzelnen Lösungen sind unten exemplarische Beispiele mit
mengenbasiertem SQL aufgeführt.
29 /41
AND dateCheck(inDate, 'mm.dd.yyyy')
AND dateCheck(inDate, 'mm.dd.yy') =
AND dateCheck(inDate, 'yyyy.mm.dd')
AND dateCheck(inDate, 'yy.mm.dd') =
then
return 'false';
else
return 'true';
end if;
--exception
--when others then return 'false';
END;
= 'false'
'false'
= 'false'
'false'
Prüfungen Kategorie B: Satz-bezogene Prüfungen.
Abhängigkeiten von anderen Feldern im selben Satz
Beispieltabelle:
F1
F2
F3
3
7
3
9
5
1
Aus- und Einschalten aller Constraints
spool test.sql
select 'alter table '||table_name||' disable constraint
'||constraint_name||';' from user_constraints where
table_name=('TABELLENNAME');
spool off
Prüfungen Kategorie A: Feld/Column-bezogene Prüfungen.
CASE in SQL-Statements / Manuelles Prüfen
SELECT
CASE
WHEN isnumeric('999') = 1 THEN 'numerisch'
ELSE 'nicht numerisch'
END Ergebnis
FROM dual;
IsNumeric-Prüfung
CREATE OR REPLACE FUNCTION isnumeric ( p_string in varchar2)
return boolean AS
l_number number;
BEGIN
l_number := p_string;
RETURN TRU;
EXCEPTION
WHEN others THEN RETURN FALSE;
END;
-CREATE OR REPLACE FUNCTION isnumeric ( p_string in varchar2)
return number AS
l_number number;
BEGIN
l_number := p_string;
RETURN 0;
EXCEPTION
WHEN others THEN RETURN 1;
END;
IsDate-Prüfung
create or replace function IsDate (str varchar2) return
varchar2 is inDate varchar2(40);
FUNCTION dateCheck (inputDate varchar2, inputMask varchar2)
RETURN varchar2
IS dateVar date;
BEGIN
dateVar:= to_date(inputDate,inputMask);
return 'true';
exception
when others then
return 'false';
END;
BEGIN
inDate:= trim(str);
if dateCheck(inDate, 'mm-dd-yyyy') = 'false'
AND dateCheck(inDate, 'mm-dd-yy') = 'false'
AND dateCheck(inDate, 'yyyy-mm-dd') = 'false'
AND dateCheck(inDate, 'yy-mm-dd') = 'false'
AND dateCheck(inDate, 'yyyy-mon-dd') = 'false‚
AND dateCheck(inDate, 'yy-mon-dd') = 'false‚
AND dateCheck(inDate, 'dd-mon-yyyy') = 'false‚
AND dateCheck(inDate, 'dd-mon-yy') = 'false‚
AND dateCheck(inDate, 'mmddyy') = 'false‚
AND dateCheck(inDate, 'mmddyyyy') = 'false‚
AND dateCheck(inDate, 'yyyymmdd') = 'false'
AND dateCheck(inDate, 'yymmdd') = 'false‚
AND dateCheck(inDate, 'yymmdd') = 'false'
AND dateCheck(inDate, 'yymondd') = 'false‚
AND dateCheck(inDate, 'yyyymondd') = 'false‚
AND dateCheck(inDate, 'mm/dd/yyyy') = 'false'
AND dateCheck(inDate, 'yyyy/mm/dd') = 'false‚
AND dateCheck(inDate, 'mm/dd/yy') = 'false'
AND dateCheck(inDate, 'yy/mm/dd') = 'false‚
Document1
F4
4
4
select
CASE
WHEN (F1 = 3 and F2 = F3 + F4)
then 1
ELSE 0
end
from fx
Satzübergfreifendes Zusammenzählen von Feldwerten (analytische
Funktion)
select Artikelname,
Artikelgruppe,
Wert,
sum(wert) over (partition by Artikelname)
Artikelgesamtwert,
sum(wert) over (partition by Artikelgruppe)
Gruppengesamtwert,
case
when
(round(((sum(wert) over (partition by
Artikelname))/(sum(wert) over (partition by
Artikelgruppe))*100),0) )
< 20
then 'ROT'
ELSE 'GRUEN'
end Prozent
from Artikel
Prüfungen Kategorie C: Satz-übergreifende Prüfungen.
Eindeutigkeitsprüfungen
Beispieltabelle
Prüfregel:
Eindeutigkeit von BESTELLNR
ist zu prüfen
insert
/*+ APPEND */ into err_non_unique_bestellung
select bestellnr from
(select
count(bestellnr) n,
bestellnr
from bestellung
group by bestellnr)
where n > 1;
Aggregatbildung und Bewerten von satzübergreifenden Summen
Beispieltabelle
Prüfregel:
Artikel
-----------------ARTIKELNAME
ARTIKELGRUPPE
WERT
Wenn der Umsatz pro Gruppe
unter 20% des Gesamtwertes
fällt, dann ROT
select Artikelname,
Artikelgruppe,
Wert,
sum(wert) over (partition by Artikelname)
Artikelgesamtwert,
sum(wert) over (partition by Artikelgruppe)
Gruppengesamtwert,
case
when
(round(((sum(wert) over (partition by
Artikelname))/(sum(wert) over (partition by
Artikelgruppe))*100),0) )
< 20
then 'ROT'
ELSE 'GRUEN'
end Prozent
from Artikel
Data Warehouse Technik im Fokus - Skripte in Kurzform
Prüfungen Kategorie D: Tabellen-übergreifende Prüfungen.
Foreign Key Prüfung
Beispieltabelle
Prüfregel:
Es darf keine Bestellung ohne
zugehörigen Kunde geben.
insert
/*+ APPEND */ into err_orphan_Bestellung
select bestellnr
from bestellung
where
Kundennr not in (select Kundennr from kunde);
Prüfungen Kategorie E: Zeit- / Zusammenhangbezogene Prüfungen.
Prüfungen Kategorie F: Verteilungen + Mengen - Prüfungen.
(Hängen von der jeweligen fachlichen Prüfung ab. Sie sind
analog zu den Prüfungen wie zuvor beschrieben durchzuführen.
Eventuell sogar mit einer Table-Function. Siehe dort)
SQL-Mittel beim Laden
Pivot/Unpivot Beispiele
WITH pivot_data AS (
SELECT Artikelnr,Bestellmenge
FROM best_pos)
SELECT *
FROM pivot_data
PIVOT(
SUM(Bestellmenge)
FOR Artikelnr
IN (1,2,3,4,5,6));
Ergebnis:
1
2
3
4
5
6
---------- ---------- ---------- ---------- ---------3398
2948
2972
2702
2900
2752
select * from sales_by_quarter pivot (sum(revenue) for quarter
in ('Q1','Q2','Q3','Q4')) order by salesrep ;
select * from quarterly_sales
unpivot include nulls (revenue for quarter in (q1,q2,q3,q4))
order by salesrep, quarter ;
Multiple Inserts /Manuelles Aufspalten von korrekten und nicht
korrekten Sätzen
1. Schritt: Füllen einer temp. Tabelle
INSERT INTO EL_KUNDE_TMP (KUNDENNR, VORNAME, NACHNAME, ORTNR,
STRASSE, TELEFON, KUNDENNR_IS_NUMERIC)
(SELECT NUMMER, NAME, NAME, NUMMER, NAME, NUMMER,
CASE isnumeric(NUMMER)
WHEN 1 THEN 1
ELSE 0
END
FROM SRC1);
2. Schritt: Auswerten Prüffeld mit Mult. Inserts
INSERT
ALL
WHEN KUNDENNR_IS_NUMERIC = 1 THEN
INTO EL_KUNDE
(KUNDENNR, VORNAME, NACHNAME, ORTNR, STRASSE, TELEFON)
VALUES
(KUNDENNR, VORNAME, NACHNAME, ORTNR, STRASSE, TELEFON)
WHEN KUNDENNR_IS_NUMERIC = 0 THEN
INTO
EL_KUNDE_FEHLER
(KUNDENNR, VORNAME, NACHNAME, ORTNR, STRASSE, TELEFON,
KUNDENNR_IS_NUMERIC)
VALUES
(KUNDENNR, VORNAME, NACHNAME, ORTNR, STRASSE, TELEFON,
KUNDENNR_IS_NUMERIC)
(SELECT
KUNDENNR, VORNAME, NACHNAME, ORTNR, STRASSE, TELEFON,
KUNDENNR_IS_NUMERIC
FROM EL_KUNDE_TMP);
Merge-Beispiel
MERGE INTO Kunde_TGT USING
(SELECT
KUNDEN_STAMM.KUNDENNR KUNDENNR,
KUNDEN_STAMM.VORNAME VORNAME,
KUNDEN_STAMM.NACHNAME NACHNAME,
KUNDEN_STAMM.STATUS STATUS,
KUNDEN_STAMM.STRASSE STRASSE,
KUNDEN_STAMM.TELEFON TELEFON,
KUNDEN_STAMM.TELEFAX TELEFAX
FROM KUNDEN_STAMM KUNDEN_STAMM) MERGE_SUBQUERY
Document1
30 /41
ON ( Kunde_TGT.KUNDENNR = MERGE_SUBQUERY.KUNDENNR)
WHEN NOT MATCHED THEN
INSERT
(Kunde_TGT.KUNDENNR,
Kunde_TGT.VORNAME,
Kunde_TGT.NACHNAME,
Kunde_TGT.STATUS,
Kunde_TGT.STRASSE,
Kunde_TGT.TELEFON,
Kunde_TGT.TELEFAX)
VALUES
(MERGE_SUBQUERY.KUNDENNR,
MERGE_SUBQUERY.VORNAME,
MERGE_SUBQUERY.NACHNAME,
MERGE_SUBQUERY.STATUS,
MERGE_SUBQUERY.STRASSE,
MERGE_SUBQUERY.TELEFON,
MERGE_SUBQUERY.TELEFAX)
WHEN MATCHED THEN UPDATE
SET
VORNAME = MERGE_SUBQUERY.VORNAME,
NACHNAME = MERGE_SUBQUERY.NACHNAME,
STATUS = MERGE_SUBQUERY.STATUS,
STRASSE = MERGE_SUBQUERY.STRASSE,
TELEFON = MERGE_SUBQUERY.TELEFON,
TELEFAX = MERGE_SUBQUERY.TELEFAX;
Flashback
Relevante Fragestellungen
Absichern von Ladeläufen und potentielles Zurückrollen von
fehlerhaft geladenen Sätzen ermöglichen.
Flashback auf die gesamte Datenbank oder auf einzelne
Tabellen.
Absichern von Direct-Path-Loads
Log-Modus / Archiv-Modus prüfen
SELECT flashback_on, log_mode FROM gv$database;
Aktuelle SCN abfragen
SELECT current_scn FROM gv$database;
Retention-Zeit abfragen
SELECT name, value FROM gv$parameter WHERE name LIKE
'%flashback%';
Ändern Retention-Zeit
ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET=2880;
(Anzahl der Minuten 60 * 24 = 1440 = 1 Tag)
Abfragen der letzten Logs
SELECT * from gv$flashback_database_log;
SELECT oldest_flashback_scn,
oldest_flashback_time
FROM gv$flashback_database_log;
Desc gv$flashback_database_log
INST_ID
OLDEST_FLASHBACK_SCN
OLDEST_FLASHBACK_TIME
RETENTION_TARGET
FLASHBACK_SIZE
ESTIMATED_FLASHBACK_SIZE
Zurücksetzen einer Tabelle auf ältere SCN mit Flashback
FLASHBACK TABLE X TO SCN 16552768;
startup mount exclusive;
FLASHBACK TABLE dwh.X TO SCN 16552768;
Beispiel Flasback
CREATE TABLE x (Nummer number);
ALTER TABLE x ENABLE ROW MOVEMENT;
INSERT INTO X VALUES (1); / Commit;
SELECT ora_rowscn FROM x;
 ORA_ROWSCN: 25489616
INSERT INTO X VALUES (1);
INSERT INTO X VALUES (1);
INSERT INTO X VALUES (1);
INSERT INTO X VALUES (1); / Commit;
SELECT ora_rowscn FROM x;
ORA_ROWSCN
---------25489743
25489743
25489743
25489743
25489743
select count(*) from x; -> 5
Flashback table x to scn 25489616;
select count(*) from x; -> 1
Relevante Dictionary Views
gv$flashback_database_log
gv$parameter
gv$database
NUMBER
NUMBER
DATE
NUMBER
NUMBER
Data Warehouse Technik im Fokus - Skripte in Kurzform
Table Function
Relevante Fragestellungen
In dem mengenbasierte Modus von SQL bleiben und dennoch
komplexere PL/SQL-Lösungen erstellen.
Table Functions gibt es in 2 Varianten:
- Pipe-Variante (Rücklieferung einzelner Sätze)
- Object-Set (Rücklieferung kompletter Tabellen)
-------------------------------------------------------------
Record / Object - Definition
Definition einer Record-Struktur: Bei der späteren Übergabe
der Daten von der Table-Funktion zu dem aufrufenden Befehl
wird diese Feld-Struktur zu Grunde gelegt.
DROP TYPE bestellung_x_t;
CREATE TYPE bestellung_x_t as OBJECT (
bestellnr
NUMBER(10),
kundencode
NUMBER(10),
bestelldatum
DATE,
bestell_total
NUMBER(12,2));
Definition einer Tabellen-Struktur
-----
Es wird die zuvor festgelegte Record-Struktur genutzt
In der FROM-Klausel des aufrufenden SELECT-Statements
wird ein Tabellen-Objekt verwendet. Dieses wird hier
festgelegt.
DROP TYPE bestellung_x_t_table;
CREATE TYPE bestellung_x_t_table as TABLE of bestellung_x_t;
-------------------------------------------------------------
Table-Function-Definition
Die Definition der Table-Function
(in diesem Beispiel werden sehr einfache Aktinen in der Table
Function gemacht, um das Prinzip aufzuzeigen)
CREATE OR REPLACE FUNCTION f_bestellung_y
RETURN bestellung_x_t_table PIPELINED
IS
bestellnr
NUMBER(10);
kundencode
NUMBER(10);
bestelldatum
DATE;
bestell_total
NUMBER(12,2);
i
number(10);
max_loops
number := 1000000;
BEGIN
i := 0;
LOOP
i := i+1;
exit when i > max_loops;
bestellnr
:= 1;
kundencode
:=12;
bestelldatum
:= sysdate ;
bestell_total := 10 ;
PIPE ROW (bestellung_x_t(bestellnr,kundencode,bestelldatum,
bestell_total));
END LOOP;
RETURN ;
END;
/
---- Beispielaufrufe
SELECT * FROM
TABLE(f_bestellung_y());
SQL / PL/SQL - Funktionen
Leeres PL/SQL-Function-Template
CREATE OR REPLACE FUNCTION "FAKULTAET"("ZAHL" IN NUMBER)
RETURN NUMBER IS
--initialize variables here
-- main body
BEGIN
NULL;
ln(n) natürlicher Algorithmus von zu e
log(m,n) Logarithmus von n zu Basis m
Beispiele
select round (21.76) from dual;
Ergebnis: 22
select trunc (21.76) from dual;
Ergebnis: 21
select trunc (21.76, -1) from dual;
Ergebnis: 20
Der zweite Parameter bei round und trunc gibt die Position der
Stelle an, an der gerundet bzw. abgeschnitten werden soll.
Positive Zahlen bedeuten Stellen nach dem Komma, negative vor
dem Komma. Gibt man den Wert nicht an greift der Defaultwert
0, der ganzzahlig rundet bzw. abschneidet.
Stringfunktionen
concat(s1, s2) s1 und s2
upper(s) s in Großbuchstaben
konkateniert (entspricht
initcap(s) erstes Zeichen
s1||s2) lower(s) s in
eines Wortes groß, Rest klein
Kleinbuchstaben
lpad(s1, n [,s2]) s1 auf n Zeichen mit s2 von links aufgefüllt
(Defaultwert für s2 ist ein Blank)
rpad(s1, n [,s2]) s1 auf n Zeichen mit s2 von rechts
aufgefüllt (Defaultwert für s2 ist ein Blank)
ltrim(s1[,s2]) alle führenden Zeichen aus s2 in s1 entfernen
(Defaultwert für s2 ist ein Blank)
rtrim(s1[,s2]) alle endenden Zeichen aus s2 in s1 entfernen
(Defaultwert für s2 ist ein Blank)
trim(s1) Kombination aus ltrim und rtrim (ab 8i)
replace(s1,s2[,s3]) suche s2 in s1 und ersetze ihn durch s3
bzw. NULL
translate(s1,s2,s3) in s1 werden alle Zeichen aus s2 durch
solche aus s3 ersetzt
substr(s,m[,n]) Teilstring von s ab Stelle m, n Zeichen lang
(n nicht angegeben => bis Stringende)
instr(s1, s2[,n[,m]]) suche s2 in s1 und zwar ab der n-ten
Stelle das m-te Auftreten (Defaultwerte für n und m sind 1),
Ergebnis ist die gefundene Position in s1 oder 0
length(s) die Länge von s
Beispiele
Teilstring bestimmen
substr('TAKTUM Informatik', 1, 6)
Ergebnis: 'TAKTUM'
Suchen
instr('TAKTUM Informatik', 'Info')
Ergebnis: 8
Zeichen erzeugen
chr(65)
Ergebnis: 'A'
Auf diese Weise können auch nicht druckbare Sonderzeichen
in einen String eingefügt werden. Allerdings muss dann der
Zeichensatz der Datenbank bekannt sein.
Zeichenkodierung erzeugen
ascii('A')
Ergebnis: 65
Teilstring ersezten
replace('SCHADE', 'D', 'LK')
Ergebnis: 'SCHALKE'
Zeichen austauschen
translate('ABC67LR5', '0123456789','**********')
Ergebnis: 'ABC**LR*'
translate('ABC67LR5', '*0123456789','*')
Ergebnis: 'ABCLR'
Auf diese Weise lassen sich unerwünschte Zeichen
elegant aus einer Zeichenkette entfernen.
-- allow compilation
RETURN NULL;
EXCEPTION
WHEN OTHERS THEN
NULL; -- enter any exception code here
RETURN NULL;
END;
Numerische Funktionen
abs(a) absoluter Wert von a
ceil(a) kleinste ganze Zahl größer als a
floor(a) größte ganze Zahl kleiner als a
mod(m,n) m Modulo n (Rest von m geteilt durch n)
power(m,n) m hoch n
round(n[,m]) n auf m Stellen gerundet
sign(a) Vorzeichen von a (0, 1 oder -1)
sin(a) Sinus von a (weitere trigonometrische Funktionen
verfügbar)
sqrt(a) Wurzel aus a
trunc(a[,m]) a auf m Stellen abgeschnitten
exp(n) liefert e hoch n (e=2,17828...)
Document1
31 /41
Datum-Funktionen
add_months(d,n) Datum d plus n Monate
last_day(d) Datum des letzten Tages des Monats, in dem d
enthalten ist
months_between(d1, d2) Anzahl der Monate zwischen d1 und d2
round(d[,fmt]) Datum d gerundet je nach Format (Defaultwert
für fmt ist 'dd' (Tag))
sysdate aktuelles Datum und Uhrzeit
trunc(d[,fmt]) Datum d abgeschnitten je nach Format
(Defaultwert für fmt ist 'dd' (Tag))
Beispiele
sysdate+1
Ergebnis: morgen um die gleiche Zeit
round(sysdate)
Ergebnis: heute um 00:00:00 Uhr
last_day(to_date('10.12.2002', 'dd.mm.yyyy'))
Ergebnis: 31.12.2002 00:00:00
months_between(to_date('25.12.2002', 'dd.mm.yyyy'),
to_date('10.11.2002', 'dd.mm.yyyy'))
Ergebnis: 1,48387097
Data Warehouse Technik im Fokus - Skripte in Kurzform
months_between(to_date('25.12.2002', 'dd.mm.yyyy'),
to_date('25.11.2002', 'dd.mm.yyyy'))
Ergebnis: 1
32 /41
Lösung 1:
select *
from auftrag
where datum = to_date ('21.09.1999', 'dd.mm.yyyy');
Als Basis zur Berechnung werden immer 31 Tage je Monat
zugrunde gelegt.
=> Problem: Was ist mit der Uhrzeit?
Bedingte Abfragen (Decode / CASE)
Lösung 2:
select *
from auftrag
where to_char (datum, 'dd.mm.yyyy') = '21.09.1999';
decode if then else
greatest(e1[,e2] ...) größter Wert der Ausdrücke
least(e1[,e2] ...) kleinster Wert der Ausdrücke
nvl(e1, e2) ist e1 NULL dann e2 sonst e1
nvl2(e1, e2, e3) ist e1 NULL dann e3 sonst e2 (ab 8i)
user aktueller Datenbankbenutzername
userenv(s) Informationen zur Benutzerumgebung
dump(e) interne Kodierung von e
vsize(e) benötigter Speicherplatz in Bytes
Beispiele
decode
(status,'A','Angelegt','E','Erledigt','S','Storniert','Unbekan
nt')
Je Nach Status werden unterschiedliche Zeichenketten zurück
geliefert. Z.b. Bei 'E' 'Erledigt'. Ist der Status nicht 'A',
'E' oder 'S' liefert decode 'Unbekannt'.
Mit decode lassen sich Berechnungen durchführen, die sonst nur
mittels Programmierung realisierbar wären. Typische
Anwendungen sind Kategorisierungen.
Die Decode-Funktion wird heute überwiegend durch CASE ersetzt
SELECT CASE WHEN (<column_value>= <value>) THEN
WHEN (<column_value> = <value>) THEN
ELSE <value>
FROM <table_name>;
Sonstige Funktionen
nvl(artikel_nr, 999999)
Ergebnis: 999999 wenn die Artikelnummer nicht gefüllt ist
sonst die Artikelnummer
greatest(4, 7, 1)
Ergebnis: 7
oder
select *
from auftrag
where trunc(datum) = to_date ('21.09.1999', 'dd.mm.yyyy');
Jeder Wert vom Datentyp date ist sekundengenau! Wird bei der
Umwandlung mit to_date die Uhrzeit nicht angegeben, so erhält
der umgewandelte Wert die Uhrzeit 0 Uhr 0 Minuten 0 Sekunden.
Beispiele
to_date ('10.08.1999', 'dd.mm.yyyy')
Ergebnis: Uhrzeit 0 Uhr 0 Min. 0 Sek
to_date ('10.08.1999 13', 'dd.mm.yyyy hh24')
Ergebnis: Uhrzeit: 13 Uhr 0 Min. 0 Sek
Zeitformat-Umwandlung
-- to_char(SQL_EXEC_START,'DD-MM-YYYY HH24:MI:SS')
'YYYY-MM-DD-HH24:MI:SS'
Select to_char(sysdate,'DD-MM-YYYY HH24:MI:SS') from dual;
 30-08-2011 15:53:52
Select to_char(sysdate,'DD.MM.YYYY HH24:MI:SS') from dual;
-> 30.08.2011 15:54:26
Select to_char(sysdate,'DD-Mon-YYYY HH24:MI:SS') from dual;
-> 30-Aug-2011 15:54:39
Konvertierung von Zahlen in Zeichenketten (to_char) und umgekehrt
(to_number)
to_char(a[,fmt]) Umwandlung der Zahl in eine Zeichenkette je
nach Format fmt.
to_char(d[,fmt]) Umwandlung des Datums d in eine Zeichenkette
je nach Format fmt.
to_date(s[,fmt]) Umwandlung der Zeichenkette s in ein Datum
to_number(s[,fmt]) Umwandlung der Zeichenkette s in eine Zahl
hextoraw(s) Umwandlung einer Zeichenkette s in Binärdaten
rawtohex(b) Umwandlung von Binärdaten b in eine Zeichenkette
mit entsprechenden Hex-Ziffern
Zahl in Zeichenketten: to_char (zahl, format)
Zeichenkette in Zahl: to_number (zeichenkette, format)
Wichtige Formatzeichen
9 Zahl 0 bis 9 ohne führende Null
0 Zahl 0 bis 9 mit führender Null
S Vorzeichen + oder D Dezimalpunkt oder Komma
G Tausenderpunkt oder Komma
FM Abschneiden von führenden Blanks
Beispiele
select to_char (anzahl * preis, '999G990D00') Umsatz
from auftrag_pos
where auftrag_nr = 1;
Beispiele
insert into druckersteuerung (befehl, code) values ('6
Zeilen/Zoll', hextoraw('1B266C3644'));
select preis * to_number ('1,8', '9D9')
from auftrag_pos
where auftrag_nr = 1;
vsize(sysdate) Ergebnis: 8
Konvertierungsfunktionen
to_char(23012.9, '000G000D00')
Ergebnis: '023.012,90'
to_char(to_date('24.12.2002','dd.mm.yyyy'),'hh24:mi:ss')
Ergebnis: '00:00:00'
Konvertierung von Datum in Zeichenkette (to_char) und umgekehrt
(to_date)
Datum in Zeichenkette: to_char (datum, format)
Zeichenkette in Datum: to_date (zeichenkette, format)
Wichtige Formatzeichen
DD Tag des Monats (1 - 31)
DAY Name des Tages ('MONTAG' bis 'SONNTAG')
day Name des Tages ('montag' bis 'sonntag')
Day Name des Tages ('Montag' bis 'Sonntag')
MM Monat des Jahres ( 1 - 12)
MON Monatsname dreistellig ('JAN' bis 'DEZ')
mon Monatsname dreistellig ('jan' bis 'dez')
Mon Monatsname dreistellig ('Jan' bis 'Dez')
MONTH Monatsname ('JANUAR' bis 'DEZEMBER')
month Monatsname ('januar' bis 'dezember')
Month Monatsname ('Januar' bis 'Dezember')
YY Jahr zweistellig (00 bis 99)
YYYY Jahr vierstellig
HH24 Uhrzeit: Stunde (0 - 24)
MI Uhrzeit: Minute (0-60)
SS Uhrzeit: Sekunde (0-60)
IW Kalenderwoche nach ISO
Q Quartal (1, 2, 3, 4)
- / , . ; : . Formatierungszeichen
beliebiger Text
Beispiele
select to_char (datum, 'dd.mm.yyyy hh24:mi:ss') Datum from
auftrag;
select to_char (to_date ('10.08.1999', 'dd.mm.yyyy'),
'dd.mm.yyyy hh24:mi:ss') from dual;
Aufgabe: Bestimme die Anzahl der Aufträge vom 21. September
1999:
Document1
Data Warehouse Technik im Fokus - Skripte in Kurzform
Verwalten des Systems /
Systembeobachtung
Relevante Fragestellungen
Systemzustände abfragen
Datenmengen abfragen
Benutzerzugriffe monitoren
Performance messen
Anzeigen der gesetzten Schwellwerte für Alerts
select metrics_name,
warning_value,
critical_value,
object_type,
object_name,
status from
dba_thresholds
Alerts abfragen
SQL> select reason from dba_outstanding_alerts;
REASON
-----------------------------------------------------Tablespace [TEST_ALERT] is [83 percent] full
Tablespace [PERF] is [93 percent] full
Tablespace [PART] is [87 percent] full
Alerts abfragen (historisch)
column OBJECT_NAMe format a50
column REASON format a50
column SUGGESTED_ACTION format a50
select CREATION_TIME,reason, OBJECT_NAME,
suggested_action from dba_alert_history;
Alert-Datei-Ablage
Show Parameter background_dump_dest
Wait Classes abfragen
select wait_class#, wait_class, count(*) from
v$event_name
group by wait_class#, wait_class
order by wait_class#
/
0 Other
717
1 Application
2 Configuration
24
3 Administrative
4 Concurrency
32
5 Commit
6 Idle
94
7 Network
8 User I/O
45
9 System I/O
10 Scheduler
7
11 Cluster
12 Queueing
9
17
54
2
35
30
50
Wait Events
select
event, wait_class,
total_waits,
total_waits_fg tw, TOTAL_TIMEOUTS_FG tt,
TOTAL_TIMEOUTS_FG from v$system_event
where wait_class != 'Idle'
and TIME_WAITED_FG >= 1000;
Menge der Undos
SELECT to_char(end_time,'DD-MM-YYYY HH24:MI:SS') ,
to_char(begin_time,'DD-MM-YYYY HH24:MI:SS') ,
undoblks
FROM v$undostat;
Informationen über die Session
Sortvorgänge auf Platte oder im Speicher
column name format a30
SELECT a.sid,a.value,b.name,c.username from
V$SESSTAT a, V$STATNAME b, v$session c
WHERE a.statistic#=b.statistic#
AND b.name LIKE 'sorts %'
and a.sid = c.sid
ORDER BY 1;
SID
VALUE NAME
USERNAME
---------- ---------- --------------------------------------67
12 sorts (memory)
MON
67
64 sorts (rows)
MON
67
0 sorts (disk)
MON
125
0 sorts (memory)
125
0 sorts (disk)
125
0 sorts (rows)
126
0 sorts (disk)
126
91 sorts (rows)
126
10 sorts (memory)
127
0 sorts (memory)
127
0 sorts (disk)
Session-Informationen
column
column
column
column
column
column
username format a15
Machine format a30
username format a10
SCHEMA format a10
machine format a18
sid format 9999
Document1
33 /41
column program format a15
column process format a10
column action format a20
SELECT
instance_name,
SID, -- NUMBER
SERIAL#, -- NUMBER
USER#, -- NUMBER
USERNAME, -- VARCHAR2(30)
SCHEMANAME as schema, -- VARCHAR2(30)
substr(machine,1,18) as machine,
terminal,
substr(PROGRAM,1,10) as program, -- VARCHAR2(48)
COMMAND, -- NUMBER
upper(decode(nvl(COMMAND, 0),
0, '---------------',
1, 'Create Table',
2, 'Insert ...',
3, 'Select. ..',
4, 'Create Cluster',
5, 'Alter Cluster',
6, 'Update. ..',
7, 'Delete. ..',
8, 'Drop. ..',
9, 'Create Index',
10, 'Drop Index',
11, 'Alter Index',
12, 'Drop Table',
13, '--',
14, '--',
15, 'Alter Table',
16, '--',
17, 'Grant',
18, 'Revoke',
19, 'Create Synonym',
20, 'Drop Synonym',
21, 'Create View',
22, 'Drop View',
23, '--',
24, '--',
25, '--',
26, 'Lock Table',
27, 'No Operation',
28, 'Rename',
29, 'Comment',
30, 'Audit',
31, 'NoAudit',
32, 'Create Ext DB',
33, 'Drop Ext. DB',
34, 'Create Database',
35, 'Alter Database',
36, 'Create RBS',
37, 'Alter RBS',
38, 'Drop RBS',
39, 'Create Tablespace',
40, 'Alter Tablespace',
41, 'Drop tablespace',
42, 'Alter Session',
43, 'Alter User',
44, 'Commit',
45, 'Rollback',
46, 'Savepoint')) job,
LOCKWAIT, -- VARCHAR2(8)
t1.STATUS, -- VARCHAR2(8)
PROCESS, -- VARCHAR2(9)
TYPE, -- VARCHAR2(10)
to_char(LOGON_TIME,'DD.MM.YYYY HH24:MI:SS'), -- DATE
ACTION, seconds_in_wait
FROM v$session t1, v$instance
order by USERNAME, SERIAL#
/
INSTANCE_NAME
SID
SERIAL#
USER# USERNAME
schema
machine
TERMINAL
program
COMMAND JOB
LOCKWAIT STATUS
PROCESS
TYPE
TO_CHAR(LOGON_TIME, ACTION
SECONDS_IN_WAIT
---------------- ----- ---------- ---------- ---------- ---------- ------------------ ---------------- --------------- --------- ----------------- -------- -------- ---------- ---------- ------------------- -------------------- --------------orcl
20
9
79 OWBSYS
OWBSYS
aschlauc
unknown
JDBC Thin
47
ACTIVE
1234
USER
13.09.2011 14:15:50 INFRASTRUCTURE
1
orcl
149
2527
151 TIF
TIF
DE-ORACLE\ASCHLAUC ASCHLAUC
sqlplus.ex
3 SELECT. ..
ACTIVE
1240:5556 USER
15.09.2011 18:20:43
0
orcl
3
1
0
SYS
ASCHLAUC
ASCHLAUC
ORACLE.EXE
0 --------------ACTIVE
284
BACKGROUND 13.09.2011 14:13:34
3
orcl
4
1
0
SYS
ASCHLAUC
ASCHLAUC
ORACLE.EXE
0 --------------ACTIVE
4684
BACKGROUND 13.09.2011 14:13:34
1
orcl
5
1
0
SYS
ASCHLAUC
ASCHLAUC
ORACLE.EXE
0 --------------ACTIVE
2704
BACKGROUND 13.09.2011 14:13:35
1
orcl
6
1
0
SYS
ASCHLAUC
ASCHLAUC
ORACLE.EXE
0 --------------ACTIVE
3356
BACKGROUND 13.09.2011 14:13:35
2
orcl
7
1
0
SYS
ASCHLAUC
ASCHLAUC
ORACLE.EXE
0 --------------ACTIVE
4308
BACKGROUND 13.09.2011 14:13:35
1201
orcl
8
1
0
SYS
ASCHLAUC
ASCHLAUC
ORACLE.EXE
0 --------------ACTIVE
4100
BACKGROUND 13.09.2011 14:13:36
0
~~~
AWR (Analytic Workload Repository)
Einstellungen
select name,value, description from v$parameter where name =
'statistics_level';
Eingestellte Intervalle
Select * from dba_hist_wr_control;
Platzverbrauch AWR messen
Select occupant_name, space_usage_kbytes from
V$SYSAUX_OCCUPANTS where occupant_name = 'SM/AWR'
Data Warehouse Technik im Fokus - Skripte in Kurzform
Auflistung bestehender Snapshots
-- Output in Trace-Datei
select
SNAP_ID,STARTUP_TIME,BEGIN_INTERVAL_TIME,END_INTERVAL_TIME,
FLUSH_ELAPSED,SNAP_LEVEL from dba_hist_snapshot;
AWR-Snapshot manuell anlegen
execute dbms_workload_repository.create_snapshot('ALL');
Snapshot-Nummern ausfindig machen
select SNAP_ID,BEGIN_INTERVAL_TIME,END_INTERVAL_TIME from
dba_hist_snapshot where snap_id > 200 order by snap_ID
Oder
select SNAP_ID,BEGIN_INTERVAL_TIME,END_INTERVAL_TIME from
dba_hist_snapshot where snap_id in (199,200)
SNAP_ID BEGIN_INTERVAL_TIME
END_INTERVAL_TIME
------- ---------------------------------------------- ---199 02-SEP-11 05.00.11.718 PM
02-SEP-11 06.00.41.875 PM
200 02-SEP-11 06.00.41.875 PM
02-SEP-11 07.00.11.984 PM
AWR-Bericht erstellen
Spool xxx
select output from
table(dbms_workload_repository.awr_report_text(1053456982,1,19
9,200));
Spool off;
[select output from
table(dbms_workload_repository.awr_report_text(1053456982,1,22
7,228)) ;]
Relevante Dictionary Views für Alerts und Session
V$SESSION
ADDM Informationen abfragen
Welche Informationen liegen vor
select task_id,recommendation_count as rc,
description from dba_advisor_tasks
where created >= trunc(sysdate);
ADDM-Analyse starten
declare
task_id number;
task_name varchar2(30) := 'ADDMdbc 3';
task_desc varchar2(30) := 'ADDM Feature Test';
begin
dbms_advisor.create_task('ADDM',task_id, task_name,
task_desc, null);
dbms_advisor.set_task_parameter(task_name,
'START_SNAPSHOT',3088);
dbms_advisor.set_task_parameter(task_name,
'END_SNAPSHOT',3089 );
dbms_advisor.set_task_parameter(task_name, 'INSTANCE',1);
dbms_advisor.set_task_parameter(task_name,
'DB_ID',1255780629);
dbms_advisor.execute_task(task_name);
end;
ADDM-Bericht anzeigen
Set long 1000000
Set pages 0
Set longchunksize 1000
Column get_clob format a80
Select dbms_advisor.get_task_report('ADDMdbc 3', 'TEXT',
'TYPICAL') from dual;
Relevante Dictionary Views für Alerts und Session
DBA_THRESHOLDS
DBA_OUTSTANDING_ALERTS
V$SESSION
V$DATABASE
34 /41
DBA_ALERT_HISTORY
V$EVENT_NAME
V$INSTANCE
DBA_ADVISOR_TASKS
*** 2011-09-05 08:08:53.468
=====================
PARSING IN CURSOR #1 len=62 dep=0 uid=0 oct=47 lid=0
tim=33718840968 hv=3081195784 ad='34ab52dc'
sqlid='2bqy8r6vufn88'
BEGIN dbms_monitor.session_trace_enable(135,181,false); END;
END OF STMT
EXEC
#1:c=0,e=1082,p=0,cr=0,cu=0,mis=1,r=1,dep=0,og=1,plh=0,tim=337
18840965
*** 2011-09-05 08:09:02.890
CLOSE #1:c=0,e=45,dep=0,type=0,tim=33728275300
=====================
PARSING IN CURSOR #3 len=41 dep=0 uid=0 oct=3 lid=0
tim=33728275601 hv=1078826809 ad='34ab4260'
sqlid='2b69gpx04v5tt'
select count(*) from dwh.wh_transaktionen
END OF STMT
PARSE
#3:c=0,e=63,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3695442063,
tim=33728275598
EXEC
#3:c=0,e=43,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3695442063,
tim=33728275918
FETCH
#3:c=0,e=792,p=0,cr=49,cu=0,mis=0,r=1,dep=0,og=1,plh=369544206
3,tim=33728276801
STAT #3 id=1 cnt=1 pid=0 pos=1 obj=0 op='SORT AGGREGATE (cr=49
pr=0 pw=0 time=0 us)'
STAT #3 id=2 cnt=4216 pid=1 pos=1 obj=86150 op='TABLE ACCESS
FULL WH_TRANSAKTIONEN (cr=49 pr=0 pw=0 time=8940 us cost=16
size=0 card=4216)'
FETCH
#3:c=0,e=3,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=3695442063,t
im=33728277502
*** 2011-09-05 08:09:15.453
CLOSE #3:c=0,e=28,dep=0,type=0,tim=33740829401
=====================
PARSING IN CURSOR #2 len=57 dep=0 uid=0 oct=47 lid=0
tim=33740830066 hv=208267310 ad='34bc4a1c'
sqlid='faaagm066mu1f'
BEGIN dbms_monitor.session_trace_disable(135,181); END;
END OF STMT
Unleserlichen Trace-Output mit TKPROF formatieren
tkprof orcl_ora_4488.trc c:\abc.txt explain=sys/sys
sort=fchqry
Session-bezogene Informationen
Session Daten abfragen
SQL> SELECT sid, serial#
FROM gv$session WHERE username = 'MON';
-> 134
/
63
Größe SGA und entsprechende Speicherbereiche
Show sga;
bzw.
select * from v$sgainfo;
Abfragen der idealen Memory-Ausnutzung
SELECT value FROM v$pgastat
WHERE name='maximum PGA allocated';
SELECT * FROM v$memory_target_advice ORDER BY memory_size;
MEMORY_SIZE
MEMORY_SIZE_FACTOR ESTD_DB_TIME
ESTD_DB_TIME_FACTOR
VERSION
Abfragen der SGA / Welche Objekte sind im Speicher
Tracing
Trace-Output-Verzeichnis
SQL> show parameter user_dump_dest
user_dump_dest
string d:\ora\diag\rdbms\orcl\orcl\trace
Identifizierung einer zu prüfenden Session
select sid,serial#,terminal,program,module from v$session;
130
131
132
135
141
1
1
1
177
1
ASCHLAUC
ASCHLAUC
ASCHLAUC
ASCHLAUC
ASCHLAUC
ORACLE.EXE (LGWR)
ORACLE.EXE (SMON)
ORACLE.EXE (MMON)
sqlplus.exe sqlplus.exe
ORACLE.EXE (CJQ0)
Aktivieren des SQL-Trace
execute dbms_monitor.session_trace_enable(135,177,true);
-- TRUE / FALS mit bzw. Ohne waits und zusätzliche Analysen
Deaktivieren
execute dbms_monitor.session_trace_disable(135,181);
Beispiel-Trace-Session
SQL> select count(*) from dwh.wh_transaktionen;
4216
SQL> execute dbms_monitor.session_trace_disable(135,181);
Document1
SET PAUSE ON
SET PAUSE 'Press Return to Continue'
SET HEADING ON
SET LINESIZE 300
SET PAGESIZE 60
COLUMN object_name FORMAT A32
SELECT t.name AS tablespace_name,
o.object_name,
SUM(DECODE(bh.status, 'free', 1, 0)) AS free,
SUM(DECODE(bh.status, 'xcur', 1, 0)) AS xcur,
SUM(DECODE(bh.status, 'scur', 1, 0)) AS scur,
SUM(DECODE(bh.status, 'cr', 1, 0)) AS cr,
SUM(DECODE(bh.status, 'read', 1, 0)) AS read,
SUM(DECODE(bh.status, 'mrec', 1, 0)) AS mrec,
SUM(DECODE(bh.status, 'irec', 1, 0)) AS irec
FROM
v$bh bh
JOIN dba_objects o ON o.object_id = bh.objd
JOIN v$tablespace t ON t.ts# = bh.ts#
where t.name not in ('SYSAUX','SYSTEM')
GROUP BY t.name, o.object_name order by o.object_name;
SELECT t.name AS tablespace_name,
o.object_name,
SUM(DECODE(bh.status, 'free', 1, 0)) AS free,
Data Warehouse Technik im Fokus - Skripte in Kurzform
SUM(DECODE(bh.status, 'xcur', 1, 0)) AS xcur,
SUM(DECODE(bh.status, 'scur', 1, 0)) AS scur,
SUM(DECODE(bh.status, 'cr', 1, 0)) AS cr,
SUM(DECODE(bh.status, 'read', 1, 0)) AS read,
SUM(DECODE(bh.status, 'mrec', 1, 0)) AS mrec,
SUM(DECODE(bh.status, 'irec', 1, 0)) AS irec
FROM
v$bh bh
JOIN dba_objects o ON o.object_id = bh.objd
JOIN v$tablespace t ON t.ts# = bh.ts#
where t.name = 'ETLDB'
GROUP BY t.name, o.object_name order by o.object_name;
Sessions schnell ‘killen’
35 /41
WHERE sample_time > SYSDATE - 1/24
AND session_type = 'FOREGROUND'
GROUP BY sql_id
ORDER BY COUNT(*) DESC;
Die aktivsten IO-Operationen
SELECT sql_id, COUNT(*)
FROM gv$active_session_history ash, gv$event_name evt
WHERE ash.sample_time > SYSDATE - 1/24
AND ash.session_state = 'WAITING'
AND ash.event_id = evt.event_id
AND evt.wait_class = 'User I/O'
GROUP BY sql_id
ORDER BY COUNT(*) DESC;
select SID,serial#,schemaname,module from v$session where TYPE
= 'USER';
alter system kill session 'sid,serial#';
set linesize 121
Schnelle Übersicht über aktuell laufende Sessions / wer / wo / was
SELECT * FROM
TABLE(dbms_xplan.display_cursor('...sql_id_#...'));
set line 200
column machine format a30
select SID,username,status,schemaname,osuser,machine,module
from v$session
where TYPE = 'USER';
SID USERNAME STATUS
SCHEMANAME OSUSER
MACHINE
MODULE
---------------6 SYS
ACTIVE
SYS
aschlauc
DEORACLE\ASCHLAUC long_proc
63 SYS
INACTIVE SYS
Administrator alfred
SQL Developer
132 MON
INACTIVE MON
aschlauc
DEORACLE\ASCHLAUC SQL*Plus
Verhindern von Memory Paging
-- lock_SGA : SGA immer im Hauptspeicher
---belassen, kein Auslagern auf Platte
alter system set lock_sga=TRUE scope=SPFILE;
Herausfinden Memory und Session
column USERNAME format a10
column name format a30
column machine format a40
SID USERNAME
PROGRAM
MACHINE
NAME
VALUE
------------------------------ ---------191 PETER
sqlplus.exe
ARBEITSGRUPPE\ALFRED
session pga memory
987364
191 PETER
sqlplus.exe
ARBEITSGRUPPE\ALFRED
session pga memory max
987364
191 PETER
sqlplus.exe
ARBEITSGRUPPE\ALFRED
session uga memory
438608
191 PETER
sqlplus.exe
ARBEITSGRUPPE\ALFRED
session uga memory max
438608
SAMPLE_TIME
EVENT
WAIT_TIME
---------------------------------- ---------------- 05-SEP-11 08.47.44.282 PM
1
05-SEP-11 08.46.42.283 PM
1
Aktives SQL Abfragen
SELECT sql_text, application_wait_time
FROM gv$sql
WHERE sql_id IN (
SELECT sql_id
FROM gv$active_session_history
WHERE TO_CHAR(sample_time) = '05-SEP-11 08.44.53.283 PM'
AND session_id = 134
AND session_serial# = 63);
SQL> desc v$session
V$STATNAME
V$MEMORY_TARGET_ADVICE
V$EVENT_NAME
ASH (Active Session History), Session + User
Informationen
Größe ASH - Buffer
SELECT *
FROM gv$sgastat WHERE name = 'ASH buffers';
Desc gv$active_session_history,
SELECT DISTINCT wait_class
FROM gv$event_name
ORDER BY 1;
Session Daten abfragen
SQL> SELECT sid, serial#
FROM gv$session WHERE username = 'MON';
-> 134
/
select
to_char(s.begin_interval_time,'mm-dd hh24') c1,
sql.sql_id
c2,
t.SQL_TEXT
C9,
sql.executions_delta
c3,
sql.buffer_gets_delta
c4,
sql.disk_reads_delta
c5,
sql.iowait_delta
c6,
sql.apwait_delta
c7,
sql.ccwait_delta
c8
from
dba_hist_sqlstat
sql,
dba_hist_snapshot
s,
dba_hist_SQLTEXT
t
where
s.snap_id = sql.snap_id
and
sql.PARSING_SCHEMA_NAME = 'DWH1' and
t.SQL_ID = sql.SQL_ID
and
sql.sql_id = '01978kjxb5yd2' and
to_char(s.begin_interval_time,'mm-dd hh24') = '09-12 13'
order by c1, c2;
Session-Informationen
Relevante Dictionary Views
63
Die aktivsten SQLs in der letzten Stunde
SELECT sql_id,COUNT(*),
ROUND(COUNT(*)/SUM(COUNT(*)) OVER(), 2) PCTLOAD
FROM gv$active_session_history
WHERE sample_time > SYSDATE - 1/24
AND session_type = 'BACKGROUND'
GROUP BY sql_id
ORDER BY COUNT(*) DESC;
SELECT sql_id,COUNT(*),ROUND(COUNT(*)/SUM(COUNT(*)) OVER(), 2)
PCTLOAD
FROM gv$active_session_history
Document1
SELECT sample_time, event, wait_time
FROM gv$active_session_history
WHERE session_id = 134
AND session_serial# = 63
Übersicht über SQL-Statements in der Vergangenheit
select s.sid, s.username, s.program, s.machine, sa.name,
sum(ss.value) value
from v$sesstat ss, v$statname sa, v$session s
where ss.sid = s.sid and (sa.name like '%pga%' or
sa.name like '%uga%')
and sa.statistic# = ss.statistic#
and s.username ='PETER'
group by s.sid,s.username, s.program, s.machine, sa.name order
by 1,2,3
V$SESSTAT
V$SESSION
V$PGASTAT
V$SYSTEM_EVENT
Sample-Time abfragen
Relevante Dictionary Views
GV$ACTIVE_SESSION_HISTORY
GV$SQL
DBA_HIST_SNAPSHOT
V$SESSION
GV$EVENT_NAME
DBA_HIST_SQLSTAT
DBA_HIST_SQLTEXT
SQL-Monitoring
SQL Cache
Der folgende Befehl zeigt für die SQL-Befehle, die sich im
SQL-Cache befinden, wie oft sie ausgeführt wurden und wieviele
Blockzugriffe sie zur Abarbeitung benötigten. Ausserdem wird
die Trefferquote des Befehls im Datencache angezeigt. Damit
lassen sich sehr schnell schlecht optimierte SQL-Befehle
herausfinden. Trefferquoten kleiner 70% deuten regelmäßig
darauf hin, dass eine Tabelle vollständig ohne Index-Zugriffe
gelesen wird. Ggf. ist ein weiterer Index hinzuzufügen, um den
Befehl zu optimieren. Da die Statistik nur die Befehle
anzeigt, die sich gerade im SQL-Cache befinden, muss die
folgende Abfrage ggf. mehrfach täglich zu unterschiedlichen
Zeitpunkten aufgerufen werden.
select to_char(executions, '999G999G990') executions,
sql_id,
to_char(buffer_gets, '999G999G990') gets,
to_char(buffer_gets/greatest(nvl(executions,1),1),
'999G999G990') gets je exec,
to_char (round(100*(1(disk_reads/greatest(nvl(buffer_gets,1),1))),2), '990D00')
Trefferquote,
substr(sql_text,1,100)
from v$sql
where buffer_gets > 1000
order by buffer_gets desc;
Data Warehouse Technik im Fokus - Skripte in Kurzform
USERNAME
executions SQL_ID
gets
gets je exec TREFFER SUBSTR(S.SQL_TEXT,1,100)
---------- ----------- ------------- ---------- -----------MON
1 azj40p0u6tykq
947,998
947,998
0.12 select distinct VERTRIEBSKANAL from BESTELLUNG_P
SYS
143 6gvch1xu9ca3g
153,871
1,076
98.75 DECLARE job BINARY_INTEGER := :job; next_date DA
Kurzabfrage auf ein bestimmtes Select-Statement mit einer bestimmten
Tabelle
column text format a50
column Module format a10
column username format a10
select substr(sql_text,1,45)
Text,
username,
module,
PX_SERVERS_ALLOCATED/2 parallel, Buffer_gets,
disk_reads
from v$SQL_MONITOR
WHERE UPPER(SQL_TEXT) LIKE '%F_UMSATZ%';
TEXT
USERNAME
MODULE
PARALLEL BUFFER_GETS DISK_READS
--------------------------------- ---------- --------------- ----------- ---------SELECT sum(u.UMSATZ) Umsatz,
DWH QL*Plus 2
40480
3269
R.REGION,
SELECT a.sparte_name, z.Jahr_Nummer, r.land,v DWH QL*Plus 2
133
0
SELECT sum(u.UMSATZ) Umsatz,
DWH QL*Plus 2
40480
7409
R.REGION,
CREATE bitmap index idx_ZEIT_ID_BM on F_UMSAT DWH QL*Plus
303230
2185
SELECT a.sparte_name, z.Jahr_Nummer, r.land,v DWH QL*Plus 2
133
23
SELECT sum(u.UMSATZ) Umsatz,
DWH QL*Plus 2
40480
0
R.REGION,
SQL-Statistik abfragen / Wurde ein Ergebniss aus dem Cache oder von
der Platte gelesen?
Set autotrace on statistics
(Führt zu zusätzlichen Statistik-Zeilen unterhalb der Ausgabe.
Ist der Wert „physical reads“ auf 0, dann wurde aus dem Cache
gelesen)
z. B.
Statistics
-------------------------------------------------------0 recursive calls
0 db block gets
7088 consistent gets
0 physical reads
692 redo size
347 bytes sent via SQL*Net to client
475 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
Abfrage auf v$sql_Monitor
column sql_text format a75
column userName format a10
select userName, status,ELAPSED_TIME, SQL_ID ,SQL_EXEC_ID,
to_char(SQL_EXEC_START,'DD-MM-YYYY HH24:MI:SS'),
substr(SQL_TEXT ,1,75) SQL_Text from v$sql_monitor order by
SQL_EXEC_START;
Eindeutigkeit über SQL_ID SQL_EXEC_START SQL_EXEC_ID
select count(*),
case
when count(*) != 1 then (count(*)-1)/2
when count(*) = 1 then count(*)
end Parallelitaet
,SQL_ID,SQL_EXEC_ID,
to_char(SQL_EXEC_START,'DD-MM-YYYY HH24:MI:SS')
from v$sql_monitor
group by SQL_ID,SQL_EXEC_ID,SQL_EXEC_START
order by to_char(SQL_EXEC_START,'DD-MM-YYYY
HH24:MI:SS'),SQL_ID,SQL_EXEC_ID;
Feststellen welche Benutzer mit welchem SQL und welcher Parallelität
zugegriffen haben
Liste aller SQLs ausser SYS seit letzten Hochfahren der DB
Rechenzeit aufsummiert über alle Prozesse
column sql_text format a75
column userName format a10
select
b.username,
a.anz_Proz,
a.Parallelitaet,
a.MilliSek_Rech_Zeit,
a.SQL_ID,
a.SQL_EXEC_ID,
a.laufzeit,
b.SQL_Text
from
(select count(*) anz_Proz,sum(ELAPSED_TIME)/1000000
MilliSek_Rech_Zeit,
case
when count(*) != 1 then (count(*)-1)/2
when count(*) = 1 then count(*)
end Parallelitaet
,SQL_ID,SQL_EXEC_ID,
to_char(SQL_EXEC_START,'DD-MM-YYYY HH24:MI:SS')
laufzeit
from v$sql_monitor
group by SQL_ID,SQL_EXEC_ID,SQL_EXEC_START
Document1
36 /41
order by to_char(SQL_EXEC_START,'DD-MM-YYYY
HH24:MI:SS'),SQL_ID,SQL_EXEC_ID) a,
(select userName, status,ELAPSED_TIME, SQL_ID
,SQL_EXEC_ID, to_char(SQL_EXEC_START,'DD-MM-YYYY HH24:MI:SS')
laufzeit,
substr(SQL_TEXT ,1,500) SQL_Text from
v$sql_monitor order by SQL_EXEC_START) b
where
a.SQL_ID
= b.SQL_ID
and
a.SQL_EXEC_ID
= b.SQL_EXEC_ID
and
a.laufzeit
= b.laufzeit and
substr(b.sql_text,1,2) != ' '
and
b.username != 'SYS'
/
USERNAME ANZ_PROZ PARALLEL MILLISEK_RECH_ZEIT SQL_ID
SQL_EXEC_ID
LAUFZEIT
SQL_TEXT
----------------- ------------- ------------------ ------------MON
9
4
146.
742371
9p3gpbg7sz1cr 16777216 22-08-2011 08:19:12 select distinct vertriebskanal from
BESTELLUNG_PART_RANGE_4
MON
9
4
146.848209 9p3gpbg7sz1cr 16777217 22-08-2011
08:20:43 select distinct vertriebskanal from BESTELLUNG_PART_RANGE_4
MON
1
158.071063 9p3gpbg7sz1cr 16777218 22-08-2011 08:23:37 select
distinct vertriebskanal from BESTELLUNG_PART_RANGE_4
PETER 1
158.029279 apzgjdwwcxb2j 16777217 22-08-2011 08:27:52 select
distinct vertriebskanal from mon.BESTELLUNG_PART_RANGE_4
PETER 5
2
106.608017 apzgjdwwcxb2j 16777218 22-08-2011
08:29:54 select distinct vertriebskanal from mon.BESTELLUNG_PART_RANGE_4
PETER 9
4
146.151807 apzgjdwwcxb2j 16777219 22-08-2011
08:30:57 select distinct vertriebskanal from mon.BESTELLUNG_PART_RANGE_4
PETER 9
4
146.675706 apzgjdwwcxb2j 16777220 22-08-2011
08:51:21 select distinct vertriebskanal from mon.BESTELLUNG_PART_RANGE_4
PETER 9
4
146.563312 apzgjdwwcxb2j 16777222 22-08-2011
10:15:54 select distinct vertriebskanal from mon.BESTELLUNG_PART_RANGE_4
PETER 9
4
146.890659 apzgjdwwcxb2j 16777223 22-08-2011
10:43:44 select distinct vertriebskanal from mon.BESTELLUNG_PART_RANGE_4
PETER 1
158.497194 apzgjdwwcxb2j 16777224 22-08-2011 10:46:01 select
distinct vertriebskanal from mon.BESTELLUNG_PART_RANGE_4
SQLTun-Report über SQL ID aufrufen
spool c:\abc
select dbms_sqltune.report_sql_monitor(
type
=> 'html',
sql_id => 'f1fj6drvxwk9h')
as sql_monitor from dual;
spool off;
Lese-Statistiken auf einzelne Tabellen gezielt abfragen
Select distinct * from
(select
to_char(begin_interval_time,'dd.mm.yyyy:hh24:MI') Zeit,
logical_reads_total log_rd,
logical_reads_delta log_rd_delta,
physical_reads_total phy_rd,
physical_reads_delta phy_rd_delta
from
dba_hist_seg_stat
s,
dba_hist_seg_stat_obj o,
dba_hist_snapshot
sn
where
o.owner = 'DWH1'
and
s.obj# = o.obj#
and
sn.snap_id = s.snap_id and
object_name = 'UMSATZ')
order by zeit;
Relevante Dictionary Views
V$SQL
V$SQL_MONITOR
DBA_HIST_SEG_STAT
DBA_HIST_SEG_STAT_OBJ
DBA_HIST_SNAPSHOT
Planmanagement
Automatisiertes Sammeln von Plänen einschalten
alter system set optimizer_capture_sql_plan_baselines=true;
Parameter zur Behandlung von Plänen
SQL> show parameter optimizer
NAME
TYPE
VALUE
------------------------------------ ----------optimizer_capture_sql_plan_baselines boolean
optimizer_dynamic_sampling integer
2
optimizer_features_enable string
11.2.0.1
optimizer_index_caching
integer
0
optimizer_index_cost_adj
integer
100
optimizer_mode
string
ALL_ROWS
optimizer_secure_view_merging
boolean
optimizer_use_invisible_indexes
boolean
optimizer_use_pending_statistics
boolean
optimizer_use_sql_plan_baselines
boolean
--------TRUE
TRUE
FALSE
FALSE
TRUE
Nutzen der Pläne einschalten
alter system set optimizer_use_sql_plan_baselines=true;
Anzeigen von Plänen in Plan_Baselines - Eingeschränkt auf einen User
select SQL_Handle, Plan_name,enabled, accepted, fixed from
dba_SQL_PLAN_BASELINES
select SQL_Handle, Plan_name,enabled, accepted, fixed,
ELAPSED_TIME, substr(SQL_TEXT,1, 50), creator from
dba_SQL_PLAN_BASELINEs where
creator = 'MON';
Data Warehouse Technik im Fokus - Skripte in Kurzform
SQL_HANDLE PLAN_NAME ENA ACC FIX ELAPSED_TIME
SUBSTR(SQL_TEXT,1,50)
------------------------------ -----------------------------SYS_SQL_115024ccba5e158c
SQL_PLAN_12n14tkx5w5cc52d2775d
YES YES NO
0 DELETE FROM PLAN_TABLE WHERE STATEMENT_ID=:1
SYS_SQL_294c437e331fa51f
SQL_PLAN_2km23gstjz98zdf463620
YES YES NO
0 SELECT PLAN_TABLE_OUTPUT FROM
TABLE(DBMS_XPLAN.DIS
SYS_SQL_2bdf77bedbcdea50
SQL_PLAN_2rrvrrvdwvukhed88afee
YES YES NO
0 SELECT CHAR_VALUE FROM SYSTEM.PRODUCT_PRIVS
WHERE
SYS_SQL_4e5c4235c17d5d62
SQL_PLAN_4wr226r0rurb22e8a86b7
YES YES NO
0 SELECT PT.VALUE FROM SYS.V_$SESSTAT PT WHERE
PT.SI
SYS_SQL_85372e07e425b213
SQL_PLAN_8adtf0zk2bchm35b3cdca
YES YES NO
0 SELECT NAME
NAME_COL_PLUS_SHOW_PARAM,DECODE(TYPE,1
SYS_SQL_967d7c5636192728
SQL_PLAN_9czbwasv1k9t8499f732f
YES YES NO
0 select distinct VERTRIEBSKANAL from
BESTELLUNG_PAR
SYS_SQL_b96c99b551913735
SQL_PLAN_bkv4tqp8t2dtp6be2eac7
YES YES NO
0 select * from tab
SYS_SQL_bff897b9dbcabe27
SQL_PLAN_bzy4rr7dwpgj7ed88afee
YES YES NO
0 SELECT
ATTRIBUTE,SCOPE,NUMERIC_VALUE,CHAR_VALUE,DA
Betrachten eines gespeicherten Plans
select * from table(
dbms_xplan.Display_sql_Plan_BASELINE(
SQL_HANDLE=> 'SYS_SQL_967d7c5636192728',
format=>'basic'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------SQL handle: SYS_SQL_967d7c5636192728
SQL text: select distinct VERTRIEBSKANAL from
BESTELLUNG_PART_RANGE_4
----------------------------------------------------------Plan name: SQL_PLAN_9czbwasv1k9t8499f732f
Plan id:
1235186479
Enabled: YES
Fixed: NO
Accepted: YES
Origin:
AUTO-CAPTURE
PLAN_TABLE_OUTPUT
-------------------------------------------------------Plan hash value: 2860783498
----------------------------------------------------------| Id | Operation
| Name|
----------------------------------------------------------|
0 | SELECT STATEMENT
|
|
|
1 | PX COORDINATOR
|
|
|
2 |
PX SEND QC (RANDOM)
| :TQ10001
|
|
3 |
HASH UNIQUE|
|
|
4 |
PX RECEIVE|
|
|
5 |
PX SEND HASH
| :TQ10000
|
|
6 |
PX BLOCK ITERATOR |
|
|
7 |
TABLE ACCESS FULL| BESTELLUNG_PART_RANGE_4 |
-----------------------------------------------------------
Evolve eines neuen Plans
set serveroutput on
set long 10000
declare
report clob;
begin
report := dbms_spm.evolve_sql_plan_baseline(
sql_handle => 'SYS_SQL_85372e07e425b213');
dbms_output.put_line(report);
end;
/
Relevante Dictionary Views
DBA_SQL_PLAN_BASELINES
Lese-Performance messen
Abschätzen Lesegeschwindigkeit (IO-Performancen)
bei dem Lesen einzelner Tabellen
-- Auslesen der Datenmenge einer Tabelle (siehe dort)
-- Messen der Zeit für einen Full Table Scan
-- Berechnen
SQL> set timing on
SQL> select count(*) from bestellung_part_Range_4;
-- liest komplette Tabelle / Full Table Scan
COUNT(*)
---------163840000
Abgelaufen: 00:00:31.32
SQL> select 7.7/31 from dual; -- Berechnen:
--Größe der Tabelle (GB) / Zeit für
--Full Table Scan (Sec) = GB/sec
7.7/31
---------,248387097
Ergibt 0,2 GB pro Sekunde Lesegeschwindigkeit
-- Test mit unterschiedlichen Parallelitäten
Parallel Sekunden GB/Sec Sekunden(2 Sessions)Sekunden(4
Sessions)
1
59~0,13 1,00/1,41/1,50/1,51
Document1
37 /41
2
4
6
8
43~0,18
30~0,25
31~0,25
30~0,25
0,53/0,57
1,28/1,40/1,52/1,55
Relevante Dictionary Views
V$SESSTAT
V$SESSION
DBA_DATA_FILES
V$STATNAME
V$IOSTAT_FILE
IO Messung / calibrate IO
disk_asynch_io
boolean
filesystemio_options
TRUE
string
SETALL
Calibrate-Status abfragen
[Kennt der Optimizer die Leistungsfähigkeit des Systems]
select status from V$IO_CALIBRATION_STATUS;
Calibrate IO abfragen
DECLARE
lat INTEGER;
iops INTEGER;
mbps INTEGER;
BEGIN
-- DBMS_RESOURCE_MANAGER.CALIBRATE_IO (<DISKS>, <MAX_LATENCY>,
iops, mbps, lat);
dbms_resource_manager.calibrate_io (4, 10, iops, mbps, lat);
dbms_output.put_line ('max_iops = ' || iops);
dbms_output.put_line ('latency = ' || lat);
dbms_output.put_line ('max_mbps = ' || mbps);
END;
/
max_iops = 164
latency = 11
max_mbps = 95
Perfstat
-- Tablespace für Perfstat-Tabellen anlegen
CREATE SMALLFILE TABLESPACE PERFSTAT NOLOGGING
DATAFILE 'D:\app\aschlauc\oradata\o11\PERFSTAT.DBF' SIZE 150M
EXTENT
MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO
-- Perfstat User einrichten (als SYS User)
$ORACLE_HOME/rdbms/admin/spcreate.sql
-- Snapshot erstellen (als PERFSTAT User)
EXECUTE statspack.snap
EXECUTE statspack.snap (i_snap_level => 7)
-- Snapshot stündlich ausführen lassen
@?/rdbms/admin/spauto.sql
--> stündlicher Aufruf
-- Spapshot Bericht erstellen lassen
D:\ora\product\11.2.0\dbhome_1\RDBMS\ADMIN>spreport.sql
Orion
Infos über
ORION -Help
ORION: ORacle IO Numbers -- Version 11.2.0.1.0
ORION runs IO performance tests that model Oracle RDBMS IO
workloads.
It measures the performance of small (2-32K) IOs and large
(128K+) IOs
at various load levels.
Aufruf über
C:\>orion -run dss -testname 'D:\Orion\laufwerk' -num_disks 4
-cache_size 0
ORION: ORacle IO Numbers -- Version 11.2.0.1.0
D:\Orion\laufwerk_20110902_1032
Calibration will take approximately 77 minutes.
Using a large value for -cache_size may take longer.
Output in Summary-File:
Command line:
-run dss -testname 'D:\Orion\laufwerk' -num_disks 4 cache_size 0
These options enable these settings:
Test: D:\Orion\laufwerk
Small IO size: 8 KB
Large IO size: 1024 KB
IO types: small random IOs, large random IOs
Sequential stream pattern: one LUN per stream
Writes: 0%
Cache size: 0 MB
Duration for each data point: 240 seconds
Small Columns:,
0
Large Columns:,
4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
48, 52, 56, 60
Data Warehouse Technik im Fokus - Skripte in Kurzform
Total Data Points: 19
Name: \\.\D:
Size: 500105217024
Name: \\.\E:
Size: 500105217024
Name: \\.\F:
Size: 500105217024
Name: \\.\G:
Size: 500105217024
4 files found.
Maximum Large MBPS=109.67 @ Small=0 and Large=56
Lesestatistiken: Werden Daten genutzt?
Select distinct * from
(select
to_char(begin_interval_time,'dd.mm.yyyy:hh24:MI') Zeit,
logical_reads_total log_rd,
logical_reads_delta log_rd_delta,
physical_reads_total phy_rd,
physical_reads_delta phy_rd_delta
from
dba_hist_seg_stat
s,
dba_hist_seg_stat_obj o,
dba_hist_snapshot
sn
where
o.owner = 'DWH1'
and
s.obj# = o.obj#
and sn.snap_id = s.snap_id
and
object_name = 'UMSATZ')
order by zeit;
ZEIT
LOG_RD LOG_RD_DELTA
PHY_RD PHY_RD_DELTA
---------------- ---------- ------------ ---------- ----------06.09.2010:22:00
3357520
3357520
3355361
3355361
06.09.2010:23:00
4030816
673296
4028177
672816
07.09.2010:12:32
8060160
4029344
8054609
4026432
07.09.2010:15:50
6886881 1
col c1 heading
col c2 heading
col c3 heading
col c4 heading
col c5 heading
col c6 heading
col c7 heading
col c8 heading
col c9 heading
break on c1
‘Begin|Interval|time’
format
‘SQL|ID’
format a13
‘Exec|Delta’
format 9,999
‘Buffer|Gets|Delta’
format
‘Disk|Reads|Delta’
format
‘IO Wait|Delta’format 9,999
‘Application|Wait|Delta’ format
‘Concurrency|Wait|Delta’ format
'SQL-Text'
format a50
a8
9,999
9,999
9,999
9,999
select
to_char(s.begin_interval_time,'mm-dd hh24') c1,
sql.sql_id
c2,
t.SQL_TEXT
C9,
sql.executions_delta
c3,
sql.buffer_gets_delta
c4,
sql.disk_reads_delta
c5,
sql.iowait_delta
c6,
sql.apwait_delta
c7,
sql.ccwait_delta
c8
from
dba_hist_sqlstat
sql,
dba_hist_snapshot
s,
dba_hist_SQLTEXT
t
where
s.snap_id = sql.snap_id
and
sql.PARSING_SCHEMA_NAME = 'DWH1' and
t.SQL_ID = sql.SQL_ID
and
sql.sql_id = '01978kjxb5yd2' and
to_char(s.begin_interval_time,'mm-dd hh24') = '09-12 13'
order by c1, c2;
Relevante Dictionary Views
DBA_HIST_SEG_STAT
DBA_HIST_SEG_STAT_OBJ
DBA_HIST_SNAPSHOT
DBA_HIST_SQLSTAT
DBA_HIST_SQLTEXT
Document1
38 /41
Data Warehouse Technik im Fokus - Skripte in Kurzform
39 /41
An Zieldatenbank einwählen
Backup im Data Warehouse
Allgemeine Überlegungen
Argumente für ein DWH spezifisches Backup-Konzept





In einem DWH sind meist größere Datenmengen zu sichern
Große datenmengen in einem DWH verursachen mehr BackupKosten
Der größte Teil der daten in einem DWH verändert sich
nicht mehr. Daher macht regelmäßiges Komplettsichern wenig
Sinn
Änderungsvorgänge findet über den ETL-Prozess in einer
kontrollierten Weise statt. Daher kennt man genau die
datenbestände, die sich geändert haben.
Backup gehört zu den teuersten Aufgaben in einem zentralen
Rechenzentrum.
Was muss gesichert werden.


Nicht gesichert werden muss:
o
Der Integration Layer (Stage)
o
Temporäre Tabellen, die im rahmen des PEL genutzt
werden
o
Read Only Tablespaces von älteren Daten in den dafür
vorgesehenen Partitionen
o
Data Marts (User View Layer), die aus dem Enterprise
Layer wieder hergestellt werden können
Gesichtert werden:
o
Die Masse der kleineren i. d. R. nicht partitionierten
Tabellen
o
Die Nicht-Read-Only Partitionen von partitionierten
Tabellen.
Connect target orcl
Welche Backups sind überflüssig
REPORT OBSOLETE;
Welche Files benötigen ein Backup
REPORT NEED BACKUP;
Leeren Recover Area
delete archivelog all;
Welche Files können nicht wiederhergestellt werden
REPORT UNRECOVERABLE;
Welche Sicherungen liegen vor
LIST BACKUP;
Alle Einstellungen von RMAN
SHOW ALL;
Definieren eines Backup-Kanals
CONFIGURE CHANNEL n DEVICE
SBT/DISK FORMAT ‘location‘;
CONFIGURE COMPRESSION ALGORITHM
‘BASIC/LOW/MEDIUM/HIGH‘;
CONFIGURE DEVICE TYPE DISK PARALLELISM 4;
Flashback aktivieren
(nur wenn Archive-Mode aktiviert ist)
shutdown immediate;
startup mount exclusive;
ALTER DATABASE FLASHBACK ON;
ALTER DATABASE OPEN;
Verwendung der Recovery Area
SELECT VALUE FROM V$PARAMETER WHERE NAME =
'db_recovery_file_dest'
Prüfen, ob Flashback aktiviert ist
SELECT flashback_on, log_mode FROM gv$database;
Prüfung des benötigten Platzes
SELECT ESTIMATED_FLASHBACK_SIZE,
RETENTION_TARGET, FLASHBACK_SIZE FROM
V$FLASHBACK_DATABASE_LOG
Retention-Zeit Flashback Area einstellen
ALTER SYSTEM SET
DB_FLASHBACK_RETENTION_TARGET=1440
Abfragen einer Tabelle von einem bestimmten SCN-Zustand
Wie wird gesichert
Es wird i. d. R. mit RMAN (Oracle Recovery Manager) gesichert.

RMAN erkennt schadhafte Blöcke und Verhindert das
Wegschreiben von diesen Blöcken so dass ein späteres
RECOVERY möglich ist.

RMAN erkennt READ-ONLY Tablespaces

RMAN kann inkrementelles Delta-Backups durchführen.
Meist macht man einmal pro Woche eine Vollsicherung (unter
Berücksichtigung der oben genannten Regeln). Innerhalb der
Woche führt man ein inkrementelles Sichern durch.
Archive Log
SELECT * FROM x AS OF SCN 12555060;
Abfragen einer Tabelle zu einer bestimmten Zeit
SELECT * FROM x AS OF TIMESTAMP to_timestamp('2012-02-15
10:15:00', 'YYYY-MM-DD HH:MI:SS');
Tabellen mit Flashback zurückholen
FLASHBACK TABLE dwh.x TO SCN 16552768;
FLASHBACK TABLE x TO SCN 16553108;
Datenbank mit Flashback zurücksetzen (Kommandobeispiele)
FLASHBACK
FLASHBACK
FLASHBACK
FLASHBACK
DATABASE
DATABASE
DATABASE
DATABASE
TO
TO
TO
TO
SCN 5964663
BEFORE SCN 5964663
TIMESTAMP (SYSDATE -1/24)
SEQUENCE 12345
Ältest mögliche Rückhol-Position feststellen
Relevante Fragestellungen
Befindet sich die Datenbank in dem Archivelog-Modus?
Der Archive-Modus stört bei Massen-INSERTS im ETL.
Festeststellen des Log-Modus der Datenbank
(als SYS-User)
SELECT LOG_MODE FROM SYS.V$DATABASE;
Ein-(Aus-)schalten des Archivelog-Modus
shutdown immediate;
startup mount
alter database archivelog;
[alter database noarchivelog;]
alter database open;
Archive-Zustand anzeigen lassen
Archive log list;
Wohin wird das Archive-Log geschrieben und wie groß ist die Recovery
Area
SHOW Parameter db_recovery_file_dest
Wie voll ist die Recovery Area aktuell
SELECT * FROM v$recovery_file_dest;
Recovery Area vergrößern
alter system set db_recovery_file_dest_size=7824M scope=both;
Relevante Dictionary Views für Alerts und Session
V$DATABASE
V$ARCHIVED_LOG
V$ARCHIVE_DEST
V$ARCHIVE_PROCESSES
RMAN
RMAN starten
Rman
Document1
V$BACKUP_REDOLOG
V$LOG
V$LOG_HISTORY
SELECT OLDEST_FLASHBACK_SCN,
OLDEST_FLASHBACK_TIME FROM
V$FLASHBACK_DATABASE_LOG
Data Warehouse Technik im Fokus - Skripte in Kurzform
Anhang
(DWH-Administrations-Checkliste - wird
aktualisiert)
Informationsbedarf planen
Anforderungen Fachanwender
Anforderungen Folgesysteme
Synchronisation der Informationen
Verhindern von doppelter Information
(3-) Schichtenmodell
Passende Aufbereitung und Präsentation
Multidimensionales Modell (Star)
Kennzahlensystem (Materialized Views-Konzept)
Dimensionen-Objekte in der Datenbank
Saubere Parent/Child-Beziehungen zwischen DimensionsLeveln
PCT bei Materialiezd Views nutzen
Aktualisierungskonzept für Materialiezed Views
Regelmäßige Prüfung ob Materialized Views genutzt werden.
Regelmäßiges Suchen nach neuen sinnvollen Materialized Views.
Staroptimierung
Passende Bitmap-Indizierung
Schlüsselverteilung im Star-Schema prüfen
Star-Transformatio einschalten
Statistiken aktuell halten
Unused-Indexes prüfen
Statistiken auf Tabellen und Index aktuell halten
ETL-Prozess mit Checkpunkten versehen
ETL-(Teil-)Prozess(e) wiederholbar machen
Vor dem Laden
Betroffene Indexe löschen
Constraints ausschalten
Logging prüfen
Direct Path prüfen
Datenqualität mit Bordmitteln machen
Partitioning gezielt einsetzen (Range / List)
Partition Exchange Load (PEL) gezielt einsetzen
ETL-Strecke monitoren
Welches sind die aufwendigen Teilstrecken?
Resourcen-Verbrauch
Werden nur die benötigten Daten gelesen?
Verlagerung von teuren Transformationen in die
Datenbank (Table Functions).
Datendurchsatz
Ist bekannt wo bei der Hardware-Umgebung die
Schwachstellen liegen?
Wird die Parallelisierung sinnvoll eingesetzt
Parallelisierung auf Einzelobjekte im ETL-Lauf und bei
Batch-Reporting.
Pauschale automatisch geregelte Parallelisierung beim
Online-Reporting.
Umgang mit Storage
Gibt es ein LifeCycle-Konzept?
Ist bekannt, welche daten oft / weniger oft genutzt
werden?
Einsatz von Flashspeicher?
40 /41
from dual
connect by level < 2000
[Auf der Community-Web-Seite gibt es vorbereitete Skripte für
umfangreichere Testdatenerzeugung:
http://www.oracledwh.de/downloads/AutoIndex2.2.4/index.php?dir=downloads/DWH_Utilities/Testdatengenerator
_V1/]
Vorgehensweise bei der Erstellung der DemoUmgebung
Beispieldaten sind zu finden unter:
http://www.oracledwh.de/downloads/AutoIndex2.2.4/index.php?dir=downloads/Kurs_Materialien_und_DWH_TIF_und
_Angebote/DWH_Reader_und_Kurzreferenz/&file=Beispieldaten_Star
_Skriptesammlung.zip
1. Das Beispiel installiert man am besten in ein separates
Benutzer-Schema in der Datenbank:
create user DWHTIF identified by DWHTIF default Tablespace
DWHTIF;
(Der Tablespace DWHTIF müßte natürlich vorhanden sein).
Man kann die Tabellen einzeln erstellen, so wie es in der
Folge unter den Punkten
2 - 5 dargestellt ist, oder man wählt die
einfachste Variante:
Man ruft nacheinander die beiden Skripte:
01_DDL_Star_Skriptesammlung.SQL
02_DML_Beispieldaten_Komplett.sql
(03_Indexe_Statistiken.sql)
2.
3.
4.
5.
Testdaten erstellen
Relevante Fragestellungen
Testdaten für Warehouse-Systeme zu Testzwecken schnell
erstellen
Das Arbeiten mit Testdaten (Erstellen und Abfragen) verrät
sehr viel über die Art und Praktikabilität des Datenmodells.
SQL-Trigger-Tabelle für Dummy-FROM-Klausel erstellen
create table zahl
level < 1000000;
as select level nr from dual
connect by
Um 51,2 Millionen Sätze zu erhalten (das ist die
Beispielmenge in dieser Skriptesammlung), muss man auf der
Basis von 100000 Sätzen den Kopiervorgang 9 mal
wiederholen.
Tabelle mit laufender Nummer erstellen
Das folgende Beispiel erzeugt eine Zähltabelle mit aufsteigend
laufender Nummer vorneweg und einer Zufallszahl von 1 bis 100.
Die neue Tabelle hat 1000 Zeilen.
create table i as
select
level nr,
dbms_random.value(1,100) Zahl
from dual
connect by level < 1000;
Das folgende Beispiel erzeugt eine Bücher-Dimension mit
aufsteigend laufender Nummer vorneweg und numerischen und
alphanumerischen Zufallswerten. Die Zieltabelle erhälz gültige
Spaltennamen.
create table d_buch as
select level
ran_abc_mixed(15)
ran_m_n(1,20)
ran_m_n(1,100)
ran_abc_mixed(20)
Document1
buch_id,
Titel,
isbn,
preis,
autor
Als erstes sind die 6 Tabellen des in der Skriptesammlung
zu Beginn abgedruckten Starschema zu erstellen. Die DDL
dazu mit Cut/Paste z. B. in SQL Plus kopieren.
a. F_Umsatz
b. D_Zeit
c. D_Kunde
d. D_Region
e. D_Artikel
f. D_Vertriebskanal
(Alternativ dazu auch die Daten DDL_Star_Skriptesammlung)
Die Daten für D_Kunde,D_Artikel, D_Vertriebskanal,D_Region
sind als Einzel-Inserts in den dazu passenden Textdateien.
Sie werden geladen:
aus dem jeweiligen Dateiverzeichnis heraus SQLPLUS
aufrufen und die Dateien mit [START Dateiname] laden.
Die Daten der Zeittabelle entstehen durch eine kleine
PL/SQL-Prozedur, der man durch Parameter den gewünschten
Zeitraum mitgeben kann.
Hierzu ist zunächst die Prozedur Time_Gen in der Textdatei
BeispielDaten_D_Zeit zu laden. (Mit Cut/Paste in SQL
Plus).
Danach kann sie aufgereufen werden mit
exec time_gen('01012000','31122015'); Das nebenstehende
Beispiel liefert Tagessätze für die Jahre 2000 bis 2015.
Als letztes sollte die Faktentabelle F_Umsatz erstellt
werden. Die Inhalte dieser Tabelle erstellt man über eine
Prozedur Umsatz_Gen, die in der Textdatei
Beispieldaten_F_Umsatz abgebildet ist (Cut/Paste in SQL
Plus)
Über einen Aufruf erzeugt man dann die gewünschte Anzahl
an Sätzen:
EXEC Umsatz_gen(100000);
In diesem Beispiel entstehen 100000 Sätze.
Um einen effektiven Test durchzuführen, benötigt man viel
mehr Sätze. Hat man z. B. 100000 Sätze mit der
Generierungsprozedur Umsatz_Gen erzeugt, sollte man diese
Anzahl durch mehrfaches Kopieren erhöhen:
Insert into F_Umsatz select * from F_Umsatz;
6.
Danach kann man die nötigen Constraints, Indexe usw.
einrichten, so wie sie in der Skritesammelung dargestellt
sind.
Hilfsprozeduren zu den Beispielmodellen
Zeitdimension
create or replace procedure Time_Gen
(startdate DATE, enddate DATE) AS
incdate DATE;
recno INTEGER;
Begin
incdate := startdate;
recno := 1;
while incdate <= enddate LOOP
insert into D_ZEIT(ZEIT_ID,
Datum_ID,
Tag_des_Monats,
Data Warehouse Technik im Fokus - Skripte in Kurzform
Tag_des_Jahres,
Woche_des_Jahres,
Monats_Nummer,
Monat_Desc,
Quartals_Nummer,
Jahr_Nummer)
Values (incdate,
recno,
TO_NUMBER(TO_CHAR(incdate,
TO_NUMBER(TO_CHAR(incdate,
TO_NUMBER(TO_CHAR(incdate,
TO_NUMBER(TO_CHAR(incdate,
TO_CHAR(incdate,
'Month'),
TO_NUMBER(TO_CHAR(incdate,
TO_NUMBER(TO_CHAR(incdate,
'DD')),
'DDD')),
'WW')),
'MM')),
'Q')),
'YYYY')));
recno := recno + 1;
incdate := incdate + 1;
END LOOP;
END;
/
--Aufruf der Prozedur z.B.:
-- alter session set nls_date_format = 'DDMMYYYY';
-- exec time_gen('01011990','31122015');
--alter session set nls_date_format = 'DD-MON-YY';
Daten in der Faktentabelle F_UMSATZ
create or replace procedure Umsatz_gen (anzahl number) AS
recno INTEGER;
v_umsatz INTEGER;
v_menge INTEGER;
BEGIN
recno := 1;
while recno <= anzahl LOOP
v_umsatz := round(dbms_random.value(1,4000));
v_menge := round(dbms_random.value(1,100));
insert into F_UMSATZ
select
round(dbms_random.value(1,129)) ARTIKEL_ID,
round(dbms_random.value(1,1031)) KUNDEN_ID,
to_date(sysdate-(round(dbms_random.value(-1000,
5000)))) ZEIT_ID,
round(dbms_random.value(1,7020)) REGION_ID,
round(dbms_random.value(1,7)) VERTRIEBS_ID,
v_umsatz UMSATZ,
v_menge MENGE,
v_umsatz * v_menge UMSATZ_GESAMT
from DUAL;
commit;
recno := recno + 1;
END LOOP;
END;
/
--Aufruf der Prozedur z.B.:
-- EXEC Umsatz_gen(100000)
-- Der Aufruf vorher erzeugt nur 100000 Sätze
-- Zum Vervielfältigen den folgenden Aufruf wählen:
-- INSERT /*+ APPEND */ into F_UMSATZ select * from F_UMSATZ;
-- Commit;
-- Diesen Befehl sooft wiederholen, bis die gewünschte Menge
erreicht ist
Document1
41 /41
Herunterladen