Oracle 10G and Windows XP

Werbung
Universität Konstanz
Information Engineering
Datenbanken und Informationssysteme
Seminar: Database Tuning & Administration
Windows XP mit Service Pack 2
&
Oracle 10g Expres Edition
Studenten:
Elena Povalyayeva
Eduard Schibrowski
Inhaltsverzeichnis:
1. Installation des Betriebsystems ............................... 3
2. Installation des Datenbankmanagementsystems Oracle 10g Expres.............................................................. 3
3. Anlegen einer neuen Datenbank und Einfügen der
„cddb“ Daten: ..................................................................... 5
4. Dupplikatenelimination und Abfragen an die
Datenbank............................................................................ 9
4.1 Datenbankstruktur: .................................................................................................... 9
4.2 Abfragen: .................................................................................................................... 11
5. Datenbank mit TCP-H Schema ................................ 13
5.1
Aufbauen der Umgebung unter Windows .................................................... 13
5.2
Erstellen der Tabellen und einspielen der TPC-H Daten .......................... 14
5.3
Generieren und ausführen der Anfragen...................................................... 16
5.4
Tuning..................................................................................................................... 17
5.4.1 Ausführzeiten der Abfragen ohne Indexes oder andere Verbesserungen. 17
5.4.2 Ausführzeiten der Abfragen mit Primary und Foregn Keys. ......................... 18
5.4.3
Ausführzeiten der Abfragen mit indexierten Tabellen.............................. 18
5.4.4 Ausführzeiten der Abfragen mit Cluster-Indexes............................................ 19
5.5
Fazit......................................................................................................................... 22
5.6
Anlagen .................................................................................................................. 23
Automatic Optimizer Statistics Collection........................................................................... 23
1. Installation des Betriebsystems
Für die Installation des Betriebsystems waren folgende Schritte notwendig:
-
Einfügen der „Windows XP“ CD mit Service Pack 1 und neu Start des
Rechners
Die System Installation wird gestartet
Die Festplatte des Rechners ist 24 GB groß, davon werden 2 Partitionen
erstellt:
o C:\ die 6 GB (5514 MB) groß ist, und die fürs System und für die
Datenbank notwendig sind
o D:\ die 18 GB groß ist und für Daten benutzt werden sollen
Während der Installation sind auch folgende Informationen angegeben worden:
-
Name des Besitzers:
DBTuner
Computen Name:
PHOBOS83
Benutzer Name
DBTuner
Administrator Passwort: dbmanager
Desweiteren werden die Netzwerktreibern installiert und die Netzwekeinstellungen
vorgenommen:
IP Adresse: 134.34.57.197 – phobos83.inf.uni-konstanz.de
Subnetzt: 255.255.0.0
Gateway: 134.34.57.1
DNS :
134.34.3.2 oder 134.34.3.3
Nach der Installation, wird das System aktualisiert mit Sevice Pack 2 und weitere
verfügbare Updates.
2. Installation des Datenbankmanagementsystems
- Oracle 10g Expres
Die Installation von Oracle wird gestartet (doppel Click auf der ausführbaren Datei).
Als Installationsverzeichniss schlägt Oracle „C:\oraclexe“ automatisch vor. Für die
Installation werden 1593016 K an Speicherplatz gebraucht.
Es wird auf dem Desktop eine Verknüpfung zu der „Erste Schritte“ Help Dateien
automatisch angelegt.
Es gibt 2 Möglichkeiten mit der Datenbank zu arbeiten:
-
über das Browser:
o Start Programs (oder All Programs) Oracle Database 10g
Express Edition Go To Database Home Page.
Man kann sich mit dem Username „system“ und dem bei der Installation
angegebenen Kennwort.
Mit der Installation ist für Trainingzwecke auch die Datenbank „User“ vorangelegt, die
mit username „hr“ ereichbar ist. Der Benutzer muss noch unlocked werden.
-
über die Kommandozeile: Start Run cmd sqlplus
Als nächstes wird es nach Benutzer Name und Passwort gefragt:
3. Anlegen einer neuen Datenbank und Einfügen
der „cddb“ Daten:
Mit dem Anlegen eines neuen Benutzer wird auch eine leere Datenbank angelegt.
Das ist wieder über Browser und über Kommandozeile möglich:
Um es über das Kommandozeile zu erstellen verwendet man folgendes Befehl:
(es werden die Pfade für die log files spezifiziert und deren Grösse, den Pfad und die
Grösse der Datenbank). Verwendung der Weiteren Parameter ist möglich.
CREATE DATABASE media
LOGFILE
'/home/oracle/log/log1media.dbf' size 20M,
'/home/oracle/log/log2.dbf' size 20M,
DATAFILE
'/home/oracle/dbs/sys1media.dbf' size 100M;
Über Browser funktioniert wie folgt:
Man loggt sich mit dem system/dbmanager ein, Administration Database Users Create Useres
Als nächstes werden die Daten Importiert. Da die *.sql Datei für Posgresql erstell
worden ist, sind auf die Daten verschiedene Bearbeitungen notwendig:
-
erstens werden die create Anfragen extrahirt und die Datentypen an Oracle
angepasst:
o varying --> varchar (Datentyp varying ist dementsprechen in
Varchar(länge) umgewandelt)
o bigint --> number (Datentyp bigint wird number)
Die Anfragen mit den geänderten Datentypen sehen wie folgt aus:
CREATE TABLE albums (
albumid number,
album varchar(80) NOT NULL
);
CREATE TABLE angebot (
angnr numeric(5,0) NOT NULL,
ort varchar(20)
);
CREATE TABLE artist2album (
artist2albumid number NOT NULL,
artistid number,
albumid number
);
CREATE TABLE artist2num_albums (
artistid number,
num_albums number
);
CREATE TABLE artists (
artistid number NOT NULL,
artist varchar(60) NOT NULL
);
CREATE TABLE cds (
cdid number NOT NULL,
artist2albumid number NOT NULL,
ayear integer,
genreid number,
discid varchar(8) NOT NULL
);
CREATE TABLE cdtracks (
songid number NOT NULL,
cdid number NOT NULL,
track integer NOT NULL
);
CREATE TABLE genres (
genreid number NOT NULL,
genre varchar(20) NOT NULL
);
CREATE TABLE song (
songid number,
song varchar(80)
);
CREATE TABLE terms_copy (
doc_id integer,
term varchar(100),
frequency integer
);
wichtig dabei ist dass man die Befehle zur Erstellung der Tabellen mit commit
abgeschlossen sein müssen.
-
zweites werden die Datensätze jeder Tabelle aus der sql Datei in separaten
Dateien kopiert und verarbeitet:
Beim Import der Daten traten im Grunde folgende Fehler ein:
- „ORA-01722: Ungültige Zahl
Import der Albums Tabelle.
Row 1: ¿1 the best of the modern years” beim
Zur Lösung dieses Problems haben wir die Spaltennamen am Anfang der Datei noch
hinzugefügt, mit Tab getrennt, so dass der erste Spaltenindex der Datei, in der
Zweiten Spalte steht. Dazu kann mann in Oracle explizit angeben dass die Datei
Spaltennamen beinhaltet.
- „ORA-20001: Load csv data error: ORA-01461: Ein LONG-Wert kann nur zur
Einfügung in eine LONG-Spalte gebunden werden“ beim Einfügen der Daten in der
Tabelle Artists.
Dafür haben wir die Datei eingelesen und in einer separaten Datei wieder
geschieben, diesmal aber ohne spezielle Zeichen (special characters).
Die Schritte zum Einfügen der Daten sind: (nach dem Anmelden mit media/media)
Schritt 1
-
Utilities Load
Schritt 2
Schritt 3
Schritt 4
Schritt 5
Schritt 6
4. Dupplikatenelimination und Abfragen an die
Datenbank.
4.1 Datenbankstruktur:
Die Datenbankstruktur sieht wie folgt aus:
Artists
ArtistID
Artist
Albums
AlbumID Album
Artists2Album
Artists2AlbumID ArtistID AlbumID
Songs
SongID
Song
cdtracks
songID cdID
Cds
cdID Artists2AlbumID ayear genreID discID
artist2num_albums
artistID
Num_albums
Genres
GenreID Genre
Angebot
AngebotID Ort
terms_copy
docID term
frequency
track
4.2 Abfragen:
//query 1
//Abgelaufen: 00:03:06.90
select "SONG"."SONG" as "SONG",
"CDS"."CDID" as "CDID",
"CDS"."AYEAR" as "AYEAR"
from "SONG" "SONG",
"CDTRACKS" "CDTRACKS",
"CDS" "CDS"
where "CDTRACKS"."SONGID"="SONG"."SONGID"
and "CDS"."CDID"="CDTRACKS"."CDID"
and "CDS"."AYEAR" >2005;
//query 2
//Abgelaufen: 00:00:00.03
select genres.genre, cds.ayear
from genres, cds
where cds.genreid=genres.genreid
and ayear >2005;
// query 3
// dauert ewig
select "ARTISTS"."ARTIST" as "ARTIST",
"ARTIST2NUM_ALBUMS"."NUM_ALBUMS" as "NUM_ALBUMS"
from "ARTIST2NUM_ALBUMS" "ARTIST2NUM_ALBUMS",
"ARTIST2ALBUM" "ARTIST2ALBUM",
"ARTISTS" "ARTISTS",
"ALBUMS" "ALBUMS"
where "ALBUMS"."ALBUMID"="ARTIST2ALBUM"."ALBUMID"
and "ARTISTS"."ARTISTID"="ARTIST2ALBUM"."ARTISTID"
and "ARTIST2NUM_ALBUMS"."ARTISTID"="ARTIST2ALBUM"."ARTISTID"
and "ARTIST2NUM_ALBUMS"."NUM_ALBUMS" > 5;
// query 4
// Abgelaufen: 00:00:01.20
select count(CDS.CDID) as "CDID",
"GENRES"."GENRE" as "GENRE"
from "GENRES" "GENRES",
"CDS" "CDS"
where "GENRES"."GENREID"="CDS"."GENREID"
group by GENRES.GENRE;
// query 5 (kleine abfrage um doppelte zeilen zu entfernen)
delete from song t1
where t1.songid in (select songid
from song t2
where t1.rowid > t2.rowid
and t1.songid = t2.songid
);
Die lätzte Abfrage entfernt die Zeilen deren ID doppelt vorkomt.
Über Kommandozeile erlaubt uns die Funktion „set timing on“ die Dauer einer Anfrage zu
messen.
Oracle erlaubt die Erstellung der Abfragen auch über GUI.
Wie in dem Screenshot ersichtlich ist kann man die Tabellen selektieren , die Felder die man
ausgeben möchte, Bedingungen hinzufügen, etc.....
Zu der in GUI erstellten Abfrage wird ein SQL Code generiert die später verbessert oder
ergänzt werden kann.
Wir haben die Abfragen ausgeführt und die Zeit gemessen. Die lätzte Abfrage haben wir gebraucht
um die Dupplikate zu entfernen. Dann haben wir für jede Tabelle jeweils ein Index angelegt und die
Abfragen erneut ausgeführt. Diesmal hat die Ausführung der Abfragen (im Schnitt) nur die Hälfte
der Zeit gebraucht.
5. Datenbank mit TCP-H Schema
5.1 Aufbauen der Umgebung unter Windows
Unter Windows ist eine Linux Umgebung notwenwendig damit „gcc“ und „make“ funktionieren.
Dafür haben wir Cygwin installiert, und zwar die „develeoper“ Version und den VIM Editor
dazu.
Nach dem Download der Dateien für den „Database Generator“ und den ” Query Generator“
müssen diese zuerst kompiliert werden. Hierzu wird eine Datei namens makefile.suite
mitgeliefert. Zuerst sollte eine Kopie der Datei mit dem Namen Makefile erstellt werden. In
dieser müssen vier Parameter zur Anpassung an die vorhandene Datenbank eingestellt
werden. Für unseren Oracle RAC passen die folgenden Werte am besten, da Oracle selbst
nicht zur Auswahl steht:
CC = gcc
DATABASE= SQLSERVER
MACHINE = LINUX
WORKLOAD = TPCH
Nach dem Speichern der Änderungen kompiliert man die Quelldateien mittels make. Dadurch
werden die beiden Tools dbgen und qgen erzeugt.
-
Editieren der Makefile:
DBTuner@phobos83 /cygdrive/e/tpch_20070105
$ cp makefile.suite ./Makefile
DBTuner@phobos83 /cygdrive/e/tpch_20070105
$ vim Makefile
- Kompilieren mit make
DBTuner@phobos83 /cygdrive/e/tpch_20070105
$ make
update_release.sh 2 6 0
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER
s.c
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER
tub.c
-DTPCH
-DTPCH
-DTPCH
-c -o build.o build.c
-c -o driver.o driver.c
-c -o bm_utils.o bm_util
-DTPCH
-DTPCH
-DTPCH
-c -o rnd.o rnd.c
-c -o print.o print.c
-c -o load_stub.o load_s
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER -DTPCH -c -o bcd2.o bcd2.c
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER -DTPCH -c -o speed_seed.o speed
_seed.c
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER -DTPCH -c -o text.o text.c
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER -DTPCH -c -o permute.o permute.
c
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER -DTPCH -c -o rng64.o rng64.c
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER -DTPCH -g -o dbgen build.o driver
.o bm_utils.o rnd.o print.o load_stub.o bcd2.o speed_seed.o text.o permute.o rng
64.o -lm
Info: resolving _optarg by linking to __imp__optarg (auto-import)
Info: resolving _optind by linking to __imp__optind (auto-import)
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER -DTPCH -c -o qgen.o qgen.c
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER -DTPCH -c -o varsub.o varsub.c
gcc -O -DDBNAME=\"dss\" -DLINUX -DSQLSERVER -DTPCH -g -o qgen build.o bm_util
s.o qgen.o rnd.o varsub.o text.o bcd2.o permute.o speed_seed.o rng64.o -lm
Info: resolving _optarg by linking to __imp__optarg (auto-import)
Info: resolving _optind by linking to __imp__optind (auto-import)
-
Aufrufen von dbgen für daten generieren
$ ./dbgen
TPC-H Population Generator (Version 2.6.0 build 1)
Copyright Transaction Processing Performance Council 1994 – 2005
-
Verzeichnis für die Daten erstellen und die Daten darin verschieben
mkdir ./data
mv *.tbl ./data
mv dss.ddl ./data
5.2 Erstellen der Tabellen und einspielen der TPC-H Daten
Als erstes, erstellt man eine neue Datenbank (indem man einen neuen Benutzer anlegt), in
unserem Fall „Xantia“.
Zweitens
müssen die Tabellen der Benchmark-Datenbank angelegt werden. Die
Tabellendefinitionen sind in der Datei dss.ddl im TPCH-Verzeichnis enthalten. Dieses Skript
wird an sqlplus üubergeben, z.B. mithilfe von:
sqlplus benutzer/passwort@datenbank < dss.ddl
Dadurch werden die Tabellendefinitionen erstellt.
Bevor man die Daten in die Datenbank einspielt sind ein paar Bearbeitungen notwendig, wie
Umwandlung der Daten vom amerikanischen in der deutschen Schreibweise:
•
•
http://www.dbasupport.com/forums/archive/index.php/t-31555.html
http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10749/ch3globenv.htm#i1007705
-
Dezimalpunkte durch Kommata ersetzten (bsp)
Starten von VIM Editor: vim customer.tbl. Dann Befehl eingeben (ohne "): ":%s/\./,/" - (ersetzt
in der ganzen datei [%], in jeder Zeile das erste Auftreten von „.“ durch „,“)
!!!! Bei der Datei lineitem.tbl tratt folgendes Problem auf: „vim out of memory“.
Daher haben wir sed benutzt (streaming editor):
sed -e 's/\./,/' -e 's/\./,/' -e 's/\./,/' lineitem.tbl > lineitem.new
ersetzt die ersten 3 Auftreten von „.“ in jeder Zeile durch „,“.
Für das Laden der Daten in die Tabellen erstellt man für jede Tabelle eine *.ctl Datei mit
folgendem Inhalt:
load data
INFILE '<filename>'
INTO TABLE <tablename>
FIELDS TERMINATED BY '<delimiter>'
<table_format>
•
Siehe: http://bhairav.serc.iisc.ernet.in/doc/Installation/Oracle.htm#load
Zum Beispiel für die Datei “lineitem” sieht der Inhalt wie folgt aus:
load data
INFILE 'LINEITEM.tbl'
INTO TABLE LINEITEM
FIELDS TERMINATED BY '|'
(L_ORDERKEY ,
L_PARTKEY ,
L_SUPPKEY ,
L_LINENUMBER ,
L_QUANTITY ,
L_EXTENDEDPRICE ,
L_DISCOUNT ,
L_TAX
,
L_RETURNFLAG ,
L_LINESTATUS ,
L_SHIPDATE "to_date(:L_SHIPDATE, 'YYYY/MM/DD')",
L_COMMITDATE "to_date(:L_COMMITDATE, 'YYYY/MM/DD')",
L_RECEIPTDATE "to_date(:L_RECEIPTDATE,
'YYYY/MM/DD')", L_SHIPINSTRUCT ,
L_SHIPMODE, L_COMMENT)
Nachdem für jede Tabelle die .ctl Datei erstellt wurde und die Daten bearbeitet, werden die
Daten eingelesen:
sqlldr xantia/xantia control=region.ctl
Der Screenshot stellt den Prozess des Einlesen der Daten dar.
Alle Daten in allen Tabellen sind erfolgreich geladen worden.
5.3 Generieren und ausführen der Anfragen
Aus dem mit 1 bis 22 benannten Abfragen werden mit dem „run qgen“ Befehl die 1_new.sql bis
22_new.sql Abfragen generiert:
In dem Ausschnitt sieht man am Beispiel die Generierung der Abfragen 1:
Für die Abfrage 1:
DBTuner@phobos83 /cygdrive/e/tpch_20070105
$ run qgen -N -d 1 > 1_new.sql
Nach der Generierung werden die Abfragen ausgeführt und die Zeit gemessen die für die
jeweiligen Abfragen notwendig ist. Bei manchen Abfragen sind Änderungen vorzunehmen
damit sie von Oracle interpretiert werden können:
-
Meistens weden die „as“ Aliases entfernt: „as shipping“, „as all_nations“, “as profit”, usw.
Die Funktion “substring” wird mit “substr” ersetzt und die Syntax angepasst indem man
„for“ und „from“ mit Kommatas ersetzt.
5.4 Tuning
Oracle Database Software ist für fast alle heute verwendeten Betriebssysteme erhältlich und als ExpressEdition (XE) kostenlos nutzbar. Allerdings ist die Express-Edition stärker als die kostenlose DB2Version eingeschränkt, weil sie Java nicht unterstützt.
5.4.1 Ausführzeiten der Abfragen ohne Indexes oder andere Verbesserungen.
In der folgenden Tabele sind die Ausführzeiten für die Abfragen eingetragen, mit und ohne
dass auf die Tabellen speziele Verbesserungsverfahren angewendet wurden. Ziel der
Untersuchung ist ein Performance-Vergleich zwischen verschiedenen Tuning-Verfahren.
Alle Abfragen haben wir von der Kommandozeile ausgeführt. Für die Messung der Zeit haben
wir die Oracle Funktion „set timing on“ aktiviert.
Query
Number
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
Without
any keys
00:29 (00005 r)
00:32 (00460 r)
00:34 (11620 r)
00:18 (00005 r)
00:20 (00005 r)
00:14 (00001 r)
00:17 (00004 r)
00:19 (00002 r)
00:29 (00175 r)
05:24 (37967 r)
00:34 (01048 r)
00:17 (00004 r)
00:11 (00042 r)
00:20 (00001 r)
00:31 (00001 r)
03:14 (18314 r)
00:44 (00001 r)
00:37 (00057 r)
00:15 (00001 r)
00:31 (00204 r)
00:48 (00411 r)
00:05 (00007 r)
Primary and Bitmap
foreign keys indexes
00:29
00:49
00:28
00:17
00:18
00:14
00:19
00:19
00:32
05:20
00:08
00:17
00:08
00:15
00:28
07:33
00:15
00:34
00:15
00:32
01:03
00:05
B
Baum
Indexes
00:55
00:42
00:56
00:64
00:56
00:45
00:62
00:59
00:77
00:56
00:21
00:62
00:13
00:54
01:51
00:04
00:53
02:19
00:42
01:05
01:45
00:02
Cluster
indexes
00:33
01:16
00:21
00:21
00:22
00:18
00:22
02:06
03:37
02:04
00:17
04:00
04:05
04:19
03:38
02:44
10:15
04:41
00:18
5.4.2 Ausführzeiten der Abfragen mit Primary und Foregn Keys.
Primary Key (Primärschlüssel) ist ein einmaliger Eintrag eines Datensatzes, damit man ihn
zweifelsfrei erkennen (und ansprechen) kann. Zum Beispiel eine automatisch hochzählende ID.
Ein Foreign Key (Fremdschlüssel) ist ein Feld in der Tabelle, der auf einen anderen Primary Key
verweist.
Die Summe aus Primary Keys und Referenzen wird unter anderem dazu genutzt vom
Datenbank System die Logische Konsistenz der Daten zu erzwingen.
5.4.3 Ausführzeiten der Abfragen mit indexierten Tabellen.
Indizes sind Zugriffspfade, bilden logische Identifizierer auf physischen ab und müssen schnell
berechenbar sein. Der interne Zugriff auf Sätze erfolgt per TID, der externe Zugriff über
benutzerdefinierte Attribute. Die Abbildung von Attributen auf TID wird über Hilfsstrukturen
realisiert. Die geläufigste Variante schneller Berechnung sind B-Bäume (Tiefensuche: Knoten
und Blätter sind Seiten). Indizes sollten auf Primärschlüssel, referentielle Integrität
(Fremdschlüssel) und eventuell häufige Suchstellen gesetzt werden.
Ein Index beschleugnigt lesende Zugriffe, verlangsamt aber Änderungsoperationen auf
indizierte Attribute, da der Index dann aktualisiert werden muss. Indexe sind logisch und
phisisch unabhängig von den Tabellendaten, somit können die Indexe jederzeit eingefügt und
auch wieder gelöscht werden.
Bitmap Indices unterscheiden sich von "normalen" Indices hauptsächlich in der internen Darstellung:
Während ein "normaler" (also ein B-Tree Index) für jeden Wert eine Liste von Rows mit dem
betreffenden Schlüssel (Schnelldenker merken: bei unique Indices ist das immer nur ein Eintrag pro
Liste) speichert, werden bei einem Bitmap Index Bitmaps (Überraschung!) für die Referenzeirung der
Daten verwendet. Dabei wird für jeden Schlüsselwert eine Folge von Bits gespeichert, wobei jedes Bit
einer Row in der Tabelle entspricht, 0 steht dann für "Row enthält diesen Schlüssel nicht" und 1 für
"Row enthält diesen Schlüssel".
Anders formuliert: B-Tree Indices speichern für jeden Schlüssel alle Rows, die diesen auch enthalten,
Bitmap Indices speichern für jeden Schlüssel alle Rows mit Kennzeichen, ob der Schlüssel enthalten ist
oder nicht. Bitmap Indices sind vor allem für Spalten mit wenigen unterschiedlichen Werten geeignet,
da speziell dann noch bei der Kombination von mehreren Kriterien, da ein AND bzw. ein OR binär ja
recht einfach zu realisieren sind.
Oracle 10g Express Edition ünterstützt keine bitmap Indexe.
Also haben wir folgende Indexe angelegt:
-
customer_idx1, der aus c_custkey und c_name besteht
lineitem_idx1, bestehend aus l_linenumber, l_orderkey, l_partkey, l_suppkey
nation_idx11 aus n_nationkey und n_name
orders_idx1 aus o_orderkey, o_custkey, o_orderdate
part_idx1, der aus P_partkey und p_partname besteht
partsupp_idx1, aus ps_partkey und ps_suppkey
region_idx1, aus r_regionkey und r_name
supplier_idx1, aus s_suppkey und s_name
5.4.4 Ausführzeiten der Abfragen mit Cluster-Indexes.
Ein Cluster ist ein Objekt, welches die Daten von einer oder mehreren Tabellen in einem Segment
speichert.
Alle Tabellen eines Clusters müssen eine oder mehrere gemeinsame Spalten enthalten, diese
gemeinsamen Spalten heißen Cluster-Schlüssel. Auf dem Cluster-Schlüssel muss zwingend ein Index
angelegt werden. Dieser Index heißt Cluster-Index und ist vom Objekttyp Index. Der Cluster sorgt dafür,
dass Daten aller Tabellen mit gleichem Cluster-Schlüssel in denselben physikalischen Blöcken liegen.
Ein Cluster ist besonders dann interessant, wenn die Tabellen im Cluster häufig verknüpft (JOIN) und
über den Cluster-Schlüssel angesprochen werden. Technisch gesehen findet also eine Optimierung des
Join auf physikalischer Ebene statt, ohne das logische Datenmodell zu ändern.
Besonders vorteilhaft ist es, wenn die Größe aller Zeilen zu einem Cluster-Schlüssel bekannt ist, dann
kann beim Erstellen des Clusters der entsprechende Speicherplatz reserviert werden. Dies geschieht mit
dem Schlüsselwort SIZE. Aus Sicht der Anwendung ist der Cluster also dann interessant, wenn bei der
1:n-Beziehung die Zahl n eine Konstante ist.
Eine sehr spezielle Form des Clusters ist der Sorted Hash Cluster, dessen Zugriff noch schneller ist, da
dessen interne Struktur sortiert ist. Hashing ist ein optionaler Weg, die Datenspeicherung zu
beeinflussen. Während bei B* - Baümen der gesamte Baum bis zu den Blätterdurchlaufen werden muss,
um an die RowID der Tupel zu gelanden, ist bei Hash-Index mitunter ein einzelnen Zugriff ausreichend.
Grundlage des Hasings ist eine Hash Funktion, die zu einem gegebenen Index einen Hash Wert
berechnet, unter dem ein Tupel zu finden ist. Da im Normallfall die Hash-Funktion nicht injektiv ist
kann es zu kolisionen komme, wenn zu zwei Tupeln derselbe Hash-Wert berechnet wird.
Die Daten werden erst nach dem Anlegen der Cluster indexe importiert. Die SQL Statements für die
Erstellung der Cluster sehen wie folgt aus:
create cluster part_partsupp_lineitem_clu (p_partkey integer) SIZE 512;
CREATE TABLE PART ( P_PARTKEY INTEGER NOT NULL,
P_NAME
VARCHAR(55) NOT NULL,
P_MFGR
CHAR(25) NOT NULL,
P_BRAND
CHAR(10) NOT NULL,
P_TYPE
VARCHAR(25) NOT NULL,
P_SIZE
INTEGER NOT NULL,
P_CONTAINER CHAR(10) NOT NULL,
P_RETAILPRICE DECIMAL(15,2) NOT NULL,
P_COMMENT VARCHAR(23) NOT NULL )
cluster part_partsupp_lineitem_clu (p_partkey);
CREATE TABLE PARTSUPP ( P_PARTKEY INTEGER NOT NULL,
PS_SUPPKEY INTEGER NOT NULL,
PS_AVAILQTY INTEGER NOT NULL,
PS_SUPPLYCOST DECIMAL(15,2) NOT NULL,
PS_COMMENT VARCHAR(199) NOT NULL )
cluster part_partsupp_lineitem_clu (p_partkey);
CREATE TABLE LINEITEM ( L_ORDERKEY INTEGER NOT NULL,
P_PARTKEY INTEGER NOT NULL,
L_SUPPKEY INTEGER NOT NULL,
L_LINENUMBER INTEGER NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX
DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL)
cluster part_partsupp_lineitem_clu (p_partkey);
create index part_partsupp_lineitem_index on cluster part_partsupp_lineitem_clu;
create cluster supplier_custom_nation_clu (s_nationkey integer)
SIZE 512;
CREATE TABLE NATION ( s_NATIONKEY INTEGER NOT NULL,
N_NAME
CHAR(25) NOT NULL,
N_REGIONKEY INTEGER NOT NULL,
N_COMMENT VARCHAR(152))
cluster supplier_custom_nation_clu (s_nationkey);
CREATE TABLE SUPPLIER ( S_SUPPKEY INTEGER NOT NULL,
S_NAME
CHAR(25) NOT NULL,
S_ADDRESS VARCHAR(40) NOT NULL,
S_NATIONKEY INTEGER NOT NULL,
S_PHONE
CHAR(15) NOT NULL,
S_ACCTBAL DECIMAL(15,2) NOT NULL,
S_COMMENT VARCHAR(101) NOT NULL)
cluster supplier_custom_nation_clu (s_nationkey);
CREATE TABLE CUSTOMER ( C_CUSTKEY INTEGER NOT NULL,
C_NAME
VARCHAR(25) NOT NULL,
C_ADDRESS VARCHAR(40) NOT NULL,
S_NATIONKEY INTEGER NOT NULL,
C_PHONE
CHAR(15) NOT NULL,
C_ACCTBAL DECIMAL(15,2) NOT NULL,
C_MKTSEGMENT CHAR(10) NOT NULL,
C_COMMENT VARCHAR(117) NOT NULL)
cluster supplier_custom_nation_clu (s_nationkey);
create index supplier_custom_nation_index on cluster supplier_custom_nation_clu;
5.5 Fazit
B-Bäume und Linear Hashing sind im allgemeinen sehr gut für dynamische Daten geeignet, die
hauptsächlich über einen Primärschlüssel angesprochen werden. Die Vorteile der schnellen Suche
werden mit höheren Aktualisierungskosten (Einfügen, Löschen) erkauft. So eignet sich Linear Hashing
zum Beispiel für das Management von Virtuellem Speicher.
Linear Hashing eignet sich wenig für die Suche nach mehreren Schlüsseln und die Bereichssuche. Da
die Daten nicht auf- oder absteigend sortiert vorliegen.
B+-Bäume erweitern die Funktion der B-Bäume um den Vorteil der guten sequentiellen Suche
(Bereichssuche). Daher sind sie sehr verbreitet und werden auch in großen Datenbankensystemen
(Oracle u.ä.) benutzt.
Bitmap-Indexe eignen sich vor allem für die mehrdimensionale Suche in großen Datenbanken, z.B. in
Data Warehouses. Dort spielen die Aktualisierungskosten kaum eine Rolle. Viel wichtiger ist die
schnelle Ausführung der Suche bei Einschränkung mehrerer Dimensionen.
Ein Blick auf die Ergebnisse wird in dem folgenden Schaubild präsentiert:
Ausführzeiten
16:48
14:24
12:00
Zeit
09:36
07:12
04:48
02:24
00:00
1
2
3
4
5
6
7
8
9
10 11 12 13 14 15 16 17 18 19 20 21 22
Abfrage Nummer
ohne tuning
primary&foreign keys
B Indexes
cluster Indexes
Die Durschnittliche Ausführzeiten der Abfragen sind auch sehr Interessant da man leicht erkennen kann
welches Verfahren zu einer Verbesserung geführt hat:
Average Time
04:48
04:19
03:50
03:21
Tim e
02:52
ohne tuning
primary and foreign keys
02:24
B Indexes
01:55
Cluster Indexes
01:26
00:57
00:28
00:00
Case
5.6 Anlagen
Automatic Optimizer Statistics Collection
By default Oracle 10g automatically gathers optimizer statistics using a scheduled job called
GATHER_STATS_JOB. By default this job runs within maintenance windows between 10 P.M. to 6 A.M. week
nights and all day on weekends. The job calls the DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC internal
procedure which gathers statistics for tables with either empty or stale statistics, similar to the
DBMS_STATS.GATHER_DATABASE_STATS procedure using the GATHER AUTO option. The main difference is
that the internal job prioritizes the work such that tables most urgently requiring statistics updates are processed
first.
In some cases automatically gathering statistics can cause problems. Highly volatile tables and load tables may
have their statistics gathered when there is an unrepresentative number of rows present. These situations can be
avoided by using one of two methods:
•
The current statistics can be deleted and locked to prevent DBMS_STATS from gathering new statistics. If
the OPTIMIZER_DYNAMIC_SAMPLING parameter is set to 2 (the default) or higher the necessary
statistics will be gathered as part of the query optimization stage (See Dynamic Sampling):
BEGIN
DBMS_STATS.delete_table_stats('MY_SCHEMA','LOAD_TABLE');
DBMS_STATS.lock_table_stats('MY_SCHEMA','LOAD_TABLE');
END;
•
•
•
•
/
•
The statistics can be gathered then locked at a time when the table contains the appropriate data:
BEGIN
DBMS_STATS.gather_table_stats('MY_SCHEMA','LOAD_TABLE');
DBMS_STATS.lock_table_stats('MY_SCHEMA','LOAD_TABLE');
END;
•
•
•
•
/
http://www.oraclebase.com/articles/10g/PerformanceTuningEnhancements10g.php#automatic_optimizer_statisti
cs_collection
Herunterladen