Performance-Vergleich von PostgreSQL, SQLite, db4o und MongoDB
Performance-Vergleich von PostgreSQL, SQLite, db4o und MongoDB
Performance-Vergleich von PostgreSQL, SQLite, db4o und MongoDB
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Performance</strong>-<strong>Vergleich</strong> <strong>von</strong><br />
<strong>PostgreSQL</strong>, <strong>SQLite</strong>, <strong>db4o</strong> <strong>und</strong> <strong>MongoDB</strong><br />
-<br />
Benchmarking <strong>und</strong> <strong>Performance</strong> <strong>von</strong> (R)DBMS<br />
Seminar Datenbanksysteme<br />
Master of Science in Engineering<br />
Vertiefungsrichtung Software and Systems<br />
HSR Hochschule für Technik Rapperswil<br />
www.hsr.ch/mse<br />
Supervisor: Prof. Stefan Keller<br />
Autoren: Philippe Morier & Martin Weber<br />
Rapperswil, Dezember 2011
Kapitel: 1 Abstract<br />
Inhalt<br />
1<br />
2<br />
3<br />
Abstract ......................................................................................................................................................... 4<br />
Aufgabenstellung ......................................................................................................................................... 5<br />
Stand der Technik ....................................................................................................................................... 6<br />
3.1 Bestehende Benchmarks .................................................................................................................... 6<br />
3.2 <strong>PostgreSQL</strong> .......................................................................................................................................... 6<br />
3.3 <strong>SQLite</strong> ...................................................................................................................................................7<br />
3.4 <strong>db4o</strong> .......................................................................................................................................................7<br />
3.5 <strong>MongoDB</strong> ............................................................................................................................................ 8<br />
4<br />
Für den Benchmark verwendete Daten ................................................................................................... 9<br />
4.1 Beschaffung & Herkunft.................................................................................................................... 9<br />
4.2 Aufbereitung ....................................................................................................................................... 9<br />
4.2.1 Extraktion ................................................................................................................................... 9<br />
5<br />
Benchmark ...................................................................................................................................................11<br />
5.1 Definition ............................................................................................................................................11<br />
5.2 Aufbau ..................................................................................................................................................11<br />
5.2.1 Datenbanken ............................................................................................................................. 13<br />
5.2.2 Durchführungsregeln ............................................................................................................... 14<br />
5.3 Benchmark-Tests <strong>und</strong> Benchmark-Ablauf .................................................................................... 15<br />
5.3.1 BMT-1 Insert - Einfügen der Test-Daten .............................................................................. 15<br />
5.3.2 BMT-2 SelectAll - Abfrage aller Daten ................................................................................. 16<br />
5.3.3 BMT-3 Equal - Abfrage auf Gleichheit ................................................................................. 17<br />
5.3.4 BMT-4 Small-/Large-Range - Kleine <strong>und</strong> grosse Bereichsabfrage ................................... 17<br />
5.3.5 BMT-5 Join - Abfrage mit Beziehungen ............................................................................... 18<br />
5.4 Test-Umgebung ................................................................................................................................. 19<br />
5.5 Effizienz-Kriterien ............................................................................................................................ 19<br />
5.6 Konfigurationen der DBMS ............................................................................................................ 19<br />
5.7 Ergebnisse <strong>und</strong> Diskussion .............................................................................................................. 19<br />
Herbst 2011 2/36
Kapitel: 1 Abstract<br />
6<br />
<strong>Vergleich</strong>barkeitsbasis & Optimierungspotentiale .............................................................................. 24<br />
6.1 Isolation-Level .................................................................................................................................. 24<br />
6.2 Datentyp-Sicherheit ......................................................................................................................... 24<br />
6.3 Einsatz <strong>von</strong> Index ............................................................................................................................. 24<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
13<br />
Schlussfolgerung ........................................................................................................................................ 26<br />
Eigenständigkeitserklärung ...................................................................................................................... 27<br />
Glossar .......................................................................................................................................................... 28<br />
Abbildungsverzeichnis .............................................................................................................................. 29<br />
Tabellenverzeichnis .................................................................................................................................... 31<br />
Literaturverzeichnis ................................................................................................................................... 32<br />
Code der Datei „benchmark.py“ ............................................................................................................. 35<br />
Herbst 2011 3/36
Kapitel: 1 Abstract<br />
1<br />
Abstract<br />
Das Datenbank-Seminar vom Herbstsemester 2011 steht u.a. unter dem Motto "Benchmarking <strong>und</strong><br />
<strong>Performance</strong> <strong>von</strong> (R)DBMS". Wir entschieden uns für einen Benchmark der folgenden DBMS<br />
durchzuführen.<br />
• <strong>PostgreSQL</strong><br />
• <strong>SQLite</strong><br />
• <strong>db4o</strong><br />
• <strong>MongoDB</strong><br />
Dabei wurde das vorliegende Dokument wie folgt strukturiert. Zu Beginn wird eine Übersicht über<br />
den Stand der Technik der vier ausgewählten DBMS gegeben. Anschliessend wird die Beschaffung<br />
<strong>und</strong> Herkunft der im Benchmark verwendeten Daten kurz beschrieben. Der Begriff „Benchmark“<br />
wird im Kapitel 6 definiert. Zudem wird in diesem Kapitel unter anderem der Aufbau <strong>und</strong> Ablauf<br />
sowie die entstandenen Resultate der Durchführung des Benchmarks aufgezeigt. Der Schluss des<br />
Dokumentes befasst sich mit der <strong>Vergleich</strong>barkeitsbasis <strong>und</strong> Optimierungspotenziale sowie eine<br />
allgemeine Schlussfolgerung.<br />
Die Abfragen für den Benchmark wurden mit der Skript-Sprache „Python“ erstellt. Diese enthalten<br />
alle durchgeführten <strong>und</strong> gemessenen Abfragen. Bei den Daten handelt es sich um Wetterdaten,<br />
welche einen Bezug zur Zeit aufweisen. Der Benchmark wurde mit den „Out-Of-The-Box“<br />
Konfigurationen des jeweiligen DBMS durchgeführt. Das DBMS „<strong>db4o</strong>“ wies mit Abstand die<br />
kleinste <strong>Performance</strong> auf.<br />
Keyword: Benchmark, db40, <strong>PostgreSQL</strong>, <strong>MongoDB</strong>, <strong>SQLite</strong>, Wetterdaten, Python, IronPython,<br />
PyMongo, DBMS, SQL<br />
Herbst 2011 4/36
Kapitel: 2 Aufgabenstellung<br />
2<br />
Aufgabenstellung<br />
Ziel dieser Arbeit ist das Erstellen <strong>und</strong> Durchführen eines Benchmarks für die folgenden vier<br />
Datenbankmanagementsysteme (DBMS).<br />
• <strong>PostgreSQL</strong><br />
• <strong>SQLite</strong><br />
• <strong>db4o</strong><br />
• <strong>MongoDB</strong><br />
Dabei ist zu beachten, dass an den einzelnen DBMS keine Konfigurationsänderungen nach deren<br />
Installation durchgeführt werden. D.h. die DBMS werden „Out-Of-The-Box“ verwendet. Des<br />
Weiteren soll eine möglichst faire <strong>Vergleich</strong>barkeitsbasis geschaffen werden <strong>und</strong> eine klar<br />
spezifizierte Test-Umgebung definiert werden. Zusätzlich soll der Aufbau, Ablauf wie auch die<br />
Schwerpunkte des Benchmarks dargestellt werden. Der Benchmark sollte Best-Practice Aufgaben<br />
beinhalten <strong>und</strong> sich allgemein anhand Best-Practice Methoden orientieren. Um die Effizienz der<br />
DBMS bestimmen zu können, sollen Effizienzkriterien definiert werden. Die Benchmark-Ergebnisse<br />
sollen in einer verständlichen Art <strong>und</strong> Weise dargestellt werden <strong>und</strong> mögliche<br />
Optimierungspotentiale sollen aufgezeigt werden.<br />
Die für den Benchmark verwendeten Daten sollen aus der Meteorologie stammen. Die Benchmark-<br />
Daten benötigen einen geografischen <strong>und</strong> zeitlichen Bezug. D.h. es sollen zeitlich abhängige Wetter-<br />
Daten verwendet werden. Zusätzlich soll darauf geachtet werden, dass eine grosse Menge an Daten<br />
für den durchzuführenden Benchmark vorliegt.<br />
Zum Schluss der Arbeit sollen die Ergebnisse des Benchmarks ausgewertet werden <strong>und</strong> die daraus<br />
gezogenen Schlussfolgerungen aufgezeigt werden.<br />
Über das gesamte Dokument hinweg gilt für die inhaltliche Bearbeitung folgende Aufteilung:<br />
• Martin Weber: <strong>SQLite</strong> & <strong>MongoDB</strong><br />
• Philippe Morier: <strong>PostgreSQL</strong> & <strong>db4o</strong><br />
Herbst 2011 5/36
Kapitel: 3 Stand der Technik<br />
3<br />
Stand der Technik<br />
Im folgendem Kapitel wird eine Liste <strong>von</strong> bestehenden Benchmarks aufgelistet. Zusätzlich werden<br />
die Eigenschaften <strong>und</strong> Spezialitäten der vier Datenbank <strong>PostgreSQL</strong>, <strong>SQLite</strong>, <strong>db4o</strong> <strong>und</strong> <strong>MongoDB</strong><br />
beschrieben.<br />
3.1 Bestehende Benchmarks<br />
Das Durchführen <strong>von</strong> Benchmarks hat in der heutigen Informatik eine grosse Bedeutung. Folgend<br />
sind Dokumente bzw. Web-Links zum Thema „Database <strong>Performance</strong> Benchmarking“ aufgelistet.<br />
• HSR Texas Geo Database Benchmark [TexasBench]<br />
• Fame Database <strong>Performance</strong> Benchmark for Time Series Data [FAME]<br />
• A Practitioner's Introduction to Database <strong>Performance</strong> Benchmarks and Measurements<br />
[OxfordJournals]<br />
• Transaction Processing <strong>Performance</strong> Council [TPC]<br />
• The Engineering Database Benchmark [Cattell]<br />
• PolePosition Open Source Database Benchmark [PolePosition]<br />
• Key/Value Pair Versus hstore - Benchmarking Entity-Attribute-Value Structures in<br />
<strong>PostgreSQL</strong> [MOtt]<br />
3.2 <strong>PostgreSQL</strong><br />
<strong>PostgreSQL</strong> ist ein objektrelationales Datenbanksystem (ORDBMS), welches im Jahr 1986 als<br />
Projekt an der University of California at Berkeley vom Hauptverantwortliche Michael Stonebraker<br />
gestartet wurde.<br />
Die Anfragesprache SQL <strong>von</strong> <strong>PostgreSQL</strong> implementiert weitgehend die Standards ANSI-SQL 92<br />
<strong>und</strong> bereits einen sehr grossen Teil der verpflichtenden Merkmale des aktuellen SQL:2008 Standard.<br />
Somit werden alle gängigen SQL-Funktionalitäten unterstützt <strong>und</strong> verhalten sich wie erwartet<br />
[Postgres].<br />
<strong>PostgreSQL</strong> wird durch die folgenden Limits eingeschränkt.<br />
Max. Datenbankgrösse<br />
Max. Tabellengrösse<br />
Max. Grösse eines Datensatzes<br />
Max. Zellengrösse<br />
Max. Anzahl Zeilen pro Tabelle<br />
Max. Anzahl der Spalten pro Tabelle<br />
Unbeschränkt<br />
32 TB<br />
1.6 TB<br />
1 GB<br />
Unbeschränkt<br />
250 - 1600 (abhängig <strong>von</strong> verwendeten Datentypen)<br />
Herbst 2011 6/36
Kapitel: 3 Stand der Technik<br />
Max. Indexes per Table<br />
Unbeschränkt<br />
Tabelle 3-1: Limits <strong>von</strong> <strong>PostgreSQL</strong> [Postgres]<br />
Für den <strong>Performance</strong>-Gewinn bei grossen Datenmengen unterstützt <strong>PostgreSQL</strong> unique-, partielle<br />
<strong>und</strong> funktionale Indexe. Seit der Version 8.1 können mehrere Indexe im Speicher zu Bitmaps<br />
verknüpft <strong>und</strong> <strong>von</strong> einem einzigen Index-Scan genutzt werden [PostgresDE]. Die Indexe werden in<br />
Form <strong>von</strong> R-Tree, B-Tree, Hash oder GiST aufgebaut [Postgres].<br />
3.3 <strong>SQLite</strong><br />
<strong>SQLite</strong> ist eine Programmbibliothek, die ein relationales Datenbanksystem enthält <strong>und</strong> einen<br />
Grossteil der im SQL-92-Standard festgelegten SQL-Sprachbefehle unterstützt. Es wurde im Jahr<br />
2000 <strong>von</strong> Richard Hipp entwickelt <strong>und</strong> ist in C programmiert [Wiki<strong>SQLite</strong>]. <strong>SQLite</strong> repräsentiert<br />
eine serverlose, konfigurationsfreie <strong>und</strong> transaktionale Datenbankengin.<br />
Ein Hauptmerkmal ist die sehr kleine Speicherplatzgrösse, welche <strong>SQLite</strong> für das Speichern der<br />
ganzen Datenbank benötigt. Je nach Systemplattform <strong>und</strong> Compiler-Optimierungseinstellung liegt<br />
der benötigte Speicherplatz bei ca. 350KB. Dies ist unter anderem ein Gr<strong>und</strong>, warum <strong>SQLite</strong> häufig<br />
in Embedded Systems zum Einsatz kommt [<strong>SQLite</strong>]. <strong>SQLite</strong> wird durch die folgenden Limits<br />
eingeschränkt.<br />
Max. Datenbankgrösse<br />
14 TB<br />
Max. involvierte Tabellen in einem Join 64<br />
Max. Grösse eines Datensatzes<br />
2 31 -1 Bytes = ca. 2 GB<br />
Max. Anzahl Zeilen pro Tabelle 2 64<br />
Max. Anzahl der Spalten pro Tabelle 32767<br />
Max. Länge eines SQL-Statements<br />
1 GB<br />
Tabelle 3-2: Limits <strong>von</strong> <strong>SQLite</strong> [SQLimits]<br />
3.4 <strong>db4o</strong><br />
Das <strong>db4o</strong> Projekt begann im Jahr 2000 unter Führung <strong>von</strong> Carl Rosenberger. Db4o ist eine open<br />
source Objektdatenbank, welche Java <strong>und</strong> .Net Entwickler ermöglicht, in ihrer Applikation Objekte<br />
mit Hilfe <strong>von</strong> wenigen Codezeilen zu speichern <strong>und</strong> abzufragen. Das Definieren <strong>und</strong> Unterhalten<br />
eines Datenbankmodells ist nicht notwendig. Db4o gehört zu den NoSQL-Datenbanken.<br />
Der Footprint der Datenbank-Bibliothek beträgt ca. 1 MB <strong>und</strong> der minimale RAM Footprint<br />
benötigt normalerweise weniger als 3 MB. Pro Datenbank-Datei ist eine maximale Grösse <strong>von</strong><br />
254GB möglich [<strong>db4o</strong>].<br />
Herbst 2011 7/36
Kapitel: 3 Stand der Technik<br />
3.5 <strong>MongoDB</strong><br />
<strong>MongoDB</strong> (<strong>von</strong> "hu-mongo-us") ist eine skalierbare, hoch-performante, dokumentenorientierte<br />
open-source Datenbank, welche in C++ geschrieben ist. Das Projekt startete im Jahr 2007 <strong>und</strong> hatte<br />
2009 den ersten öffentlichen Release. Bei der Entwicklung <strong>von</strong> <strong>MongoDB</strong> wurde besonders auf<br />
folgende vier Kriterien geachtet [<strong>MongoDB</strong>].<br />
• Flexibilität<br />
• Power<br />
• Geschwindigkeit<br />
• Einfache Verwendung<br />
Tabelle 3-3: Philosophie <strong>von</strong> <strong>MongoDB</strong><br />
Eine markante schlecht dokumentiere Begrenzung liegt in der maximalen Dateigrösse <strong>von</strong> 2.5 GB<br />
auf einem 32Bit-System [<strong>MongoDB</strong>].<br />
Herbst 2011 8/36
Kapitel: 4 Für den Benchmark verwendete Daten<br />
4<br />
Für den Benchmark verwendete Daten<br />
4.1 Beschaffung & Herkunft<br />
Die für den Benchmark verwendeten Daten stammen vom Niederschlagsradar <strong>von</strong> NZZ Online<br />
[NZZ]. Der Niederschlagsradar ist in Form einer animierten Bildserie verfügbar. Die Bildserie<br />
verwendet das Graphics Interchange Format (GIF) für die Darstellung. Um einen geografischen <strong>und</strong><br />
zeitlichen Bezug herstellen zu können, müssen zuerst die meteorologischen Daten aus der Bildserie<br />
extrahiert werden. Dieser Prozess wird <strong>von</strong> einer separaten Software-Lösung durchgeführt <strong>und</strong> für<br />
die jeweiligen DBMS in das passende Format gebracht.<br />
4.2 Aufbereitung<br />
Abbildung 4-1: Niederschlagsradar <strong>von</strong> NZZ Online<br />
4.2.1 Extraktion<br />
Die für uns interessanten Daten sind die eingefärbten Niederschlag-Pixel. Diese müssen also aus der<br />
Bilderserie extrahiert werden.<br />
Abbildung 4-2: Extraktion der Niederschlag-Pixel<br />
Herbst 2011 9/36
Kapitel: 4 Für den Benchmark verwendete Daten<br />
Jeder einzelne Niederschlags-Pixel wird in die Datenbank abgespeichert. Dabei werden als<br />
Koordinaten die Pixelpositionen vom Bild verwendet. Somit hat beispielsweise ein Niederschlags-<br />
Pixel über Rapperswil die X/Y-Koordinaten (351/108).<br />
Abbildung 4-3: Einzelner Niederschlags-Pixel<br />
Herbst 2011 10/36
Kapitel: 5 Benchmark<br />
5<br />
Benchmark<br />
5.1 Definition<br />
Ein Benchmark ist ein klar definiertes Bewertungsverfahren <strong>von</strong> EDV-Systemen. Dabei werden<br />
unterschiedliche Systeme anhand festgelegten Effizienz-Kriterien auf deren Leistung miteinander<br />
verglichen. Es existieren Benchmarks für Soft- wie auch für Hardware. In dieser Arbeit werden<br />
verschiedene DBMS miteinander verglichen. Das in dieser Arbeit beschriebenen resp.<br />
durchgeführten Bewertungsverfahren stellt somit einen Software-Benchmark dar.<br />
Das Bewertungsverfahren benötigt eine faire <strong>Vergleich</strong>barkeitsbasis um die verschiedenen EDV-<br />
Systeme miteinander zu vergleichen. Eine faire <strong>Vergleich</strong>sbarkeitsbasis beruht auf Definitionen einer<br />
Test-Umgebung, Effizienzkriterien <strong>und</strong> Konfigurationsgrad. Der Ablauf <strong>und</strong> die Durchführung des<br />
Benchmarks auf dem jeweiligen System sollte stets identisch erfolgen. Des Weiteren sollten die im<br />
Benchmark durchgeführten Aufgaben Best-Practice Anwendungsfällen entsprechen.<br />
5.2 Aufbau<br />
Im folgendem Kapitel wird der Aufbau des Benchmarks erläutert. Dabei wird der Zusammenhang<br />
der unterschiedlichen Scripts <strong>und</strong> Dateien dargestellt.<br />
Abbildung 5-1: Aufbau des Benchmarks<br />
Der Platzhalter „DBName“ steht jeweils für das konkrete Datenbankmanagementsystem <strong>und</strong> kann<br />
folgende Werte annehmen:<br />
• postgres<br />
• sqlite<br />
Herbst 2011 11/36
Kapitel: 5 Benchmark<br />
• <strong>db4o</strong><br />
• mongoDB<br />
Dies Bedeutet, dass <strong>von</strong> einer Datei, welche in der oben gezeigten Abbildung den Platzhalter enthält,<br />
jeweils vier unterschiedliche Exemplare existieren.<br />
_start_[DBName].bat<br />
Die Aufgabe der Batch-Dateien liegt darin, das entsprechende Log-File zu löschen <strong>und</strong> anschliessend<br />
die Datei „benchmark.py“ mit der richtigen Konfiguration auszuführen. D.h. es muss der<br />
entsprechende Interpreter <strong>und</strong> die passenden Parameter angegeben werden. Folgende Tabelle zeigt<br />
den Inhalt der Batch-Datei für das DBMS „<strong>db4o</strong>“.<br />
DEL <strong>db4o</strong>_log.csv<br />
ipy benchmark.py -d <strong>db4o</strong> -n 2<br />
PAUSE<br />
Abbildung 5-2: Inhalt der Datei „_start_<strong>db4o</strong>.bat“<br />
_init_[DBName].py<br />
Das init-Modul wird für das Erstellen einer sauberen Ausgangslage zur Durchführung des<br />
Benchmarks verwendet. Dabei werden alte Datenbanken gelöscht <strong>und</strong> allfällig durch einen früher<br />
durchgeführten Benchmark erstellte Dateien entfernt. In einem weiteren Schritt wird eine leere<br />
Datenbank angelegt. Zum Schluss wird die für die weitere Arbeit benötigte Verbindung zur<br />
Datenbank erstellt.<br />
_insert_[DBName].py<br />
Die für den Benchmark benötigten Daten werden durch das insert-Modul in die jeweilige Datenbank<br />
eingefügt. Insgesamt werden ca. 325‘000 Datensätze gespeichert.<br />
_queries_[DBName].py<br />
Das query-Modul enthält folgende für den Benchmark relevanten Datenbankabfragen.<br />
• Abfrage aller Daten<br />
• Abfrage auf Gleichheit<br />
• Kleine <strong>und</strong> grosse Bereichsabfrage<br />
• Join-Abfrage<br />
benchmarks.py<br />
Die Datei „benchmark.py“ stellt einen Rahmen für den Ablauf dar. D.h. sie ruft die<br />
datenbankspezifischen Methoden der importierten Module in einer fixen Reihenfolge auf. Für die<br />
Ausführung des Benchmarks werden zwei Parameter erwartet. Konkret sind dies der Name des<br />
Herbst 2011 12/36
Kapitel: 5 Benchmark<br />
DBMS <strong>und</strong> die Anzahl Durchführungen. Folgendes Beispiel führt den Benchmark für das DBMS<br />
„<strong>db4o</strong>“ zwei Mal durch.<br />
benchmark.py -d <strong>db4o</strong> -n 2<br />
Abbildung 5-3: Ausführung des Benchmarks mit entsprechenden Parameter<br />
Das benchmark-Modul übernimmt zusätzlich die Zeitmessung <strong>und</strong> das Logging. Die Zeitmessung<br />
wurde vom HSR Texas Geo Database Benchmark [TexasBench] übernommen.<br />
5.2.1 Datenbanken<br />
Die beiden RDBMS „<strong>PostgreSQL</strong>“ <strong>und</strong> „<strong>SQLite</strong>“ enthalten jeweils genau die Tabelle „raindrop“ mit<br />
folgendem Aufbau.<br />
frameId nextFrameId rainfall timestamp x y<br />
1 2 -3026176 1321389385 412 103<br />
2 3 -16749278 1321448502 431 133<br />
Tabelle 5-1: Aufbau der Tabelle "raindrop" mit Beispiel Datensätze<br />
CREATE TABLE raindrop (<br />
frameId int NOT NULL,<br />
nextFrameId int NOT NULL,<br />
rainfall int NOT NULL,<br />
timestamp int NOT NULL,<br />
x int NOT NULL,<br />
y int NOT NULL<br />
)<br />
Abbildung 5-4: Struktur der Tabelle "raindrop"<br />
Das objektorientierte DBMS „<strong>db4o</strong>“ <strong>und</strong> das dokumentorientierte DBMS „<strong>MongoDB</strong>“ haben<br />
konzeptbedingt keine Tabellen. Da das DBMS „<strong>db4o</strong>“ in erster Linie nur für Java bzw. .Net<br />
Entwickler zur Verfügung steht, musste mit einer speziellen Python-Implementation namens<br />
„IronPython“ gearbeitet werden. Diese ermöglicht das Verwalten <strong>von</strong> .Net-Objekte mit „<strong>db4o</strong>“ aus<br />
einem Python-Skript. Das Abspeichern <strong>von</strong> Python-Objekte führte zum folgendem Fehler.<br />
Unexpected char '$'<br />
Abbildung 5-5: Fehler beim Abspeichern [IrPyObj]<br />
Aus diesem Gr<strong>und</strong> wurde eine .Net-Library mit dem benötigten Klasse erstellt. Nun werden<br />
Instanzen <strong>von</strong> der .Net-Klasse mit IronPython in eine „<strong>db4o</strong>“-Datenbank abgespeichert [IrPyObj].<br />
Die Struktur der Objekte, welche für das DBMS „<strong>db4o</strong>“ verwendet werden, sieht wie folgt aus.<br />
Herbst 2011 13/36
Kapitel: 5 Benchmark<br />
Abbildung 5-6: Klasse "raindrop"<br />
Bei dem DBMS „<strong>MongoDB</strong>“ werden sogenannte Dokumente in Form <strong>von</strong> BSON (Binary JSON)<br />
abgespeichert. Diese Dokumente bzw. Objekte haben folgende Struktur.<br />
[{"frameId":1, "nextFrameId":2, "rainfall":-16746204,<br />
"timestamp":1321485558, "x":201, "y":13},<br />
{"frameId":1, "nextFrameId":2, "rainfall":-16746204,<br />
"timestamp":1321485559, "x":241, "y":54},<br />
{"frameId":2, "nextFrameId":3, "rainfall":-16053338,<br />
"timestamp":1321485560, "x":295, "y":90},<br />
{"frameId":3, "nextFrameId":4, "rainfall":-855552,<br />
"timestamp":1321485561, "x":318, "y":120}]<br />
Abbildung 5-7: "raindrop"-Dokument<br />
Damit Objekte über Python in eine <strong>MongoDB</strong> abgespeichert werden können, muss Python mit der<br />
Distribution „PyMongo“ erweitert werden [PyMongo] [Niall].<br />
5.2.2 Durchführungsregeln<br />
Für die Durchführung des Benchmarks werden die folgenden Regeln befolgt.<br />
• Jeder Test wird genau sechs Mal hintereinander durchgeführt.<br />
• Jeder Test wird auf demselben System durchgeführt.<br />
• Während der Durchführung eines Tests sind die nicht in den Test involvierten DBMS beendet.<br />
• Die verwendeten Daten aus der Meteorologie stammen aus einem realen Szenario.<br />
• Jedes DBMS hat dieselben Daten für die Tests gespeichert.<br />
Herbst 2011 14/36
Kapitel: 5 Benchmark<br />
• Die Konfigurationen der installierten DBMS wurden nach deren Installation unverändert<br />
belassen. D.h. Jedes DBMS läuft mit den Standard-Einstellungen resp. Konfigurationen <strong>und</strong> ist<br />
somit nicht optimiert (Out-Of-The-Box).<br />
5.3 Benchmark-Tests <strong>und</strong> Benchmark-Ablauf<br />
In diesem Kapitel soll die Reihenfolge <strong>und</strong> die Art der Abfragen aufgezeigt <strong>und</strong> erklärt werden.<br />
Folgende Auflistung zeigt die Anzahl, Reihenfolge <strong>und</strong> Art der Interaktionen mit dem<br />
entsprechendem DBMS. Zu beachten ist, dass bei jedem Benchmark-Test (BMT) eine allgemein<br />
identische Ausgangslage erstellt wird. D.h. allfällige Dateien oder Datenbanken werden gelöscht<br />
bzw. neu erstellt.<br />
Führe „benchmark.py“ n-Mal für Datenbank d aus<br />
Stelle Initial-Zustand her<br />
Einfügen der Test-Daten<br />
Führe m-Mal aus<br />
Abfrage aller Daten<br />
Führe m-Mal aus<br />
Abfrage auf Gleichheit<br />
Führe m-Mal aus<br />
Kleine <strong>und</strong> grosse Bereichsabfrage<br />
Führe m-Mal aus<br />
Join-Abfrage<br />
Abbildung 5-8: Struktogramm des Ablaufs<br />
Das Python-Script „benchmark.py“ nimmt die drei Parameter „n“, „m“ <strong>und</strong> „d“ entgegen. Die<br />
Parameter haben folgende Bedeutung:<br />
• n: Bestimmt die gesamte Durchführungsanzahl des Benchmarks<br />
• m: Bestimmt die Anzahl der einzelnen Interaktionen<br />
• d: Bestimmt das DBMS für welches der Benchmark ausgeführt wird<br />
5.3.1 BMT-1 Insert - Einfügen der Test-Daten<br />
Für die Durchführung des Benchmarks wird ein Datenvolumen <strong>von</strong> ca. 325’ooo Datensätze<br />
verwendet. Diese werden zu Beginn des Benchmarks in die jeweilige Datenbank eingefügt. Im<br />
Folgenden wird pro DBMS eine verkürzte Variante des Codes, welcher die Daten einfügt, aufgezeigt.<br />
Herbst 2011 15/36
Kapitel: 5 Benchmark<br />
cur = db.cursor()<br />
cur.execute("""<br />
INSERT INTO raindrop (frameId, nextFrameId, rainfall, timestamp, x, y)<br />
VALUES ('2', '3', '-16749278', '1321448502', '431', '133');<br />
INSERT INTO raindrop (frameId, nextFrameId, rainfall, timestamp, x, y)<br />
VALUES ('2', '3', '-16742359', '1321448503', '431', '134');<br />
INSERT INTO raindrop (frameId, nextFrameId, rainfall, timestamp, x, y)<br />
VALUES ('2', '3', '-15912437', '1321448504', '431', '135');<br />
""")<br />
cur.close()<br />
Abbildung 5-9: Einfügen der Test-Daten in "<strong>PostgreSQL</strong>"<br />
c = db.cursor()<br />
raindrop =<br />
[<br />
(0, 1, -855552, 1321285563, 2, 269),<br />
(0, 1, -16713984, 1321285564, 3, 270),<br />
(0, 1, -855552, 1321285565, 3, 271)<br />
]<br />
c.executemany("INSERT INTO raindrop(frameId, nextFrameId, rainfall, timestamp,<br />
x, y) values (?,?,?,?,?,?)", raindrop)<br />
c.close()<br />
Abbildung 5-10: Einfügen der Test-Daten in "<strong>SQLite</strong>"<br />
db.Store(Raindrop(0, 1, -855552, 1321285563, 2, 269))<br />
db.Store(Raindrop(0, 1, -16713984, 1321285564, 3, 270))<br />
db.Store(Raindrop(0, 1, -855552, 1321285565, 3, 271))<br />
db.Store(Raindrop(0, 1, -5832704, 1321285566, 4, 272))<br />
db.Store(Raindrop(0, 1, -16446452, 1321285567, 5, 9))<br />
Abbildung 5-11: Einfügen der Test-Daten in "<strong>db4o</strong>"<br />
raindrops = db.raindrop<br />
raindrop =<br />
[<br />
{"frameId":1, "nextFrameId":2, "rainfall":-16746204,<br />
"timestamp":1321485558, "x":201, "y":13},<br />
{"frameId":1, "nextFrameId":2, "rainfall":-16746204,<br />
"timestamp":1321485559, "x":241, "y":54}<br />
]<br />
raindrops.insert(raindrop)<br />
Abbildung 5-12: Einfügen der Test-Daten in "<strong>MongoDB</strong>"<br />
Die Test-Daten für die <strong>MongoDB</strong> wurden in zwei separate Dateien aufgeteilt. Dies wurde nötig, da<br />
ansonsten das Einfügen der Daten durch eine Memory-Exception abgebrochen wurde<br />
[MemoryError].<br />
5.3.2 BMT-2 SelectAll - Abfrage aller Daten<br />
Im Folgenden wird pro DBMS einen Code-Ausschnitt, welcher alle Daten abfragt, aufgezeigt.<br />
Herbst 2011 16/36
Kapitel: 5 Benchmark<br />
cursor.execute("""SELECT count(*) FROM raindrop""")<br />
Abbildung 5-13: Abfragen aller Test-Daten in "<strong>PostgreSQL</strong>" <strong>und</strong> „<strong>SQLite</strong>“<br />
query.Constrain(clr.GetClrType(Raindrop))<br />
result = query.Execute()<br />
Abbildung 5-14: Abfragen aller Test-Daten in "<strong>db4o</strong>"<br />
db.raindrop.find().count()<br />
Abbildung 5-15: Abfragen aller Test-Daten in "<strong>MongoDB</strong>"<br />
5.3.3 BMT-3 Equal - Abfrage auf Gleichheit<br />
Im Folgenden wird pro DBMS einen Code-Ausschnitt, welcher die Daten mit der x-Koordinate 200<br />
abfragt, aufgezeigt.<br />
cursor.execute("""SELECT count(*) FROM raindrop WHERE x = 200""")<br />
Abbildung 5-16: Abfragen der Test-Daten auf x-Koordinate 200 in "<strong>PostgreSQL</strong>"<br />
cursor.execute('SELECT count(*) FROM raindrop WHERE x=200')<br />
Abbildung 5-17: Abfragen der Test-Daten auf x-Koordinate 200 in "<strong>SQLite</strong>"<br />
query.Constrain(clr.GetClrType(Raindrop))<br />
query.Descend("_x").Constrain(200)<br />
result = query.Execute()<br />
Abbildung 5-18: Abfragen der Test-Daten auf x-Koordinate 200 in "<strong>db4o</strong>"<br />
db.raindrop.find({"x": 200}).count()<br />
Abbildung 5-19: Abfragen der Test-Daten auf x-Koordinate 200 in "<strong>MongoDB</strong>"<br />
5.3.4 BMT-4 Small-/Large-Range - Kleine <strong>und</strong> grosse Bereichsabfrage<br />
Im Folgenden wird pro DBMS einen Code-Ausschnitt, welcher die Daten mit der x-Koordinate 200<br />
abfragt, aufgezeigt.<br />
Folgende Code-Ausschnitte zeigen eine Abfrage über einen Bereich der Test-Daten. Dabei werden<br />
zwei unterschiedlich grosse Bereiche abgefragt. Bei der kleineren Abfrage wird nur einen Zehntel<br />
<strong>und</strong> bei der grösseren Abfrage die mittlere Hälfte der Daten ausgelesen. Folgende Abbildung zeigt<br />
die betroffenen Regionen der beiden Abfragen.<br />
Herbst 2011 17/36
Kapitel: 5 Benchmark<br />
Abbildung 5-20: Betroffene Regionen<br />
cursor.execute("""SELECT count(*) FROM raindrop<br />
WHERE timestamp BETWEEN 1321448503 AND 1321481090""")<br />
Abbildung 5-21: Abfragen der Test-Daten auf einen Bereich in "<strong>PostgreSQL</strong>"<br />
cursor.execute('SELECT count(*) FROM raindrop<br />
WHERE timestamp BETWEEN 1321448503 AND 1321481090')<br />
Abbildung 5-22: Abfragen der Test-Daten auf einen Bereich in "<strong>SQLite</strong>"<br />
query.Constrain(clr.GetClrType(Raindrop))<br />
query.Descend("_timestamp").Constrain(1321448502).Greater()<br />
.And(query.Descend("_timestamp").Constrain(1321481091).Smaller())<br />
result = query.Execute()<br />
Abbildung 5-23: Abfragen der Test-Daten auf einen Bereich in "<strong>db4o</strong>"<br />
db.raindrop.find({"timestamp":{'$gt':1321448502, '$lt':1321481091}}).count()<br />
Abbildung 5-24: Abfragen der Test-Daten auf einen Bereich in "<strong>MongoDB</strong>"<br />
5.3.5 BMT-5 Join - Abfrage mit Beziehungen<br />
In der Join-Abfrage werden alle Datensätze eines Frames ausgelesen, welches das nachfolgende<br />
Frame eines einzelnen Datensatzes ist. Zu beachten ist, dass das objekt- <strong>und</strong> dokumentorientierte<br />
DBMS konzeptbedingt keine Join-Abfrage direkt unterstützen. Deshalb wurden für das DBMS<br />
„<strong>db4o</strong>“ <strong>und</strong> „<strong>MongoDB</strong>“ die Join-Abfrage manuell implementiert.<br />
cursor.execute("""SELECT count(*) FROM raindrop AS a<br />
INNER JOIN raindrop AS b ON b.frameId = a.nextFrameId<br />
WHERE a.timestamp = 1321448502""")<br />
Abbildung 5-25: Join-Abfragen in "<strong>PostgreSQL</strong>"<br />
cursor.execute('SELECT count(*) FROM raindrop AS a INNER JOIN raindrop AS b ON<br />
b.frameId = a.nextFrameId WHERE a.timestamp = 1321448502')<br />
Abbildung 5-26: Join-Abfragen in "<strong>SQLite</strong>"<br />
Herbst 2011 18/36
Kapitel: 5 Benchmark<br />
query.Constrain(clr.GetClrType(Raindrop))<br />
query.Descend("_timestamp").Constrain(1321448502)<br />
result = query.Execute()<br />
query = db.Query()<br />
query.Constrain(clr.GetClrType(Raindrop))<br />
query.Descend("_frameId").Constrain(result[0].NextFrameId)<br />
result = query.Execute()<br />
Abbildung 5-27: Join-Abfragen in "<strong>db4o</strong>"<br />
rd = db.raindrop.find_one({"timestamp": 1321448502})<br />
db.raindrop.find({"frameId": rd['nextFrameId']}).count()<br />
Abbildung 5-28: Join-Abfragen "<strong>MongoDB</strong>"<br />
5.4 Test-Umgebung<br />
Für den Benchmark wurde folgendes System verwendet.<br />
System Type<br />
Model<br />
Prozessor<br />
RAM<br />
Hard Drive<br />
64-Bit Operating System<br />
HP Compaq 8710p<br />
Intel® Core 2 Duo CPU T9300 @ 2.50GHz<br />
4.00 GB<br />
Fujitsu MHZ2250BH G2 ATA Device (250GB, 5400 RPM)<br />
Operating System Windows Professional 7<br />
Tabelle 5-2: Systemeigenschaften<br />
5.5 Effizienz-Kriterien<br />
Im Durchgeführten Benchmark wird als Effizienz-Kriterium einzig die Zeit betrachtet. Weitere<br />
Kriterien wie RAM-Auslastung, CPU-Auslastung <strong>und</strong> Speicherplatz der Datenbank wären denkbar.<br />
5.6 Konfigurationen der DBMS<br />
Wie bereits in der Aufgabenstellung erwähnt, werden die jeweiligen DBMS „Out-Of-The-Box“<br />
verwendet. D.h. es werden keine eigenen Änderungen an den Konfigurationen vorgenommen. Somit<br />
werden die Standardkonfigurationen der DBMS bei belassen.<br />
5.7 Ergebnisse <strong>und</strong> Diskussion<br />
In diesem Kapitel werden die Ergebnisse der BMTs 1 bis 6 aufgezeigt. Diese sind im Kapitel [5.3<br />
Benchmark-Tests <strong>und</strong> Benchmark-Ablauf] genauer erläutert. Dabei zeigt jedes Diagramm sechs<br />
Durchführungen der jeweiligen Interaktion (z.B. Insert, Join, etc.).<br />
Herbst 2011 19/36
Kapitel: 5 Benchmark<br />
Auf Gr<strong>und</strong> der Übersicht sind die Achsen der jeweiligen Plots nicht beschrieben. In jedem Plot sind<br />
auf der X-Achse die sechs nacheinander durchgeführten Benchmarks. Die Y-Achse zeigt die jeweilige<br />
Dauer in Sek<strong>und</strong>en. Die Farben der Balken in den Diagrammen repräsentieren je ein DBMS.<br />
Folgende Legende gilt für die untenstehenden Diagramme.<br />
<strong>SQLite</strong><br />
<strong>PostgreSQL</strong><br />
<strong>db4o</strong><br />
<strong>MongoDB</strong><br />
Abbildung 5-29: Ergebnisse des Benchmarks<br />
Herbst 2011 20/36
Kapitel: 5 Benchmark<br />
Bestimmte DBMS benötigen für das erstmalige Einfügen der Daten deutlich länger als bei erneuten<br />
Einfüge-Aktionen. So dauert das erste Einfügen bei „<strong>db4o</strong>“ ca. 40 Sek<strong>und</strong>en. Anschliessende<br />
Einfüge-Aktionen benötigen nur noch zwischen 10 <strong>und</strong> 15 Sek<strong>und</strong>en. Dies stellt eine ca. dreifache<br />
Verbesserung dar.<br />
Der SelectAll-Plot weisst ein ähnliches Verhalten wie der Insert-Plot auf. Die „<strong>MongoDB</strong>“ zeigt ein<br />
enorme Verbesserungen bei erneuten Abfrage aller Daten. Wobei der Fokus auf der ersten Abfrage<br />
liegt. Diese dauert ca. 40 mal länger als bei anderen Datenbanken! Dafür benötigt sie für die weiteren<br />
SelectAll-Abfragen praktisch keine Zeit mehr.<br />
In den restlichen vier Plots zeigt sich, dass „<strong>db4o</strong>“ deutlich langsamer die gestellten Interaktionen<br />
verarbeitet. Unserer Meinung nach liegt der Gr<strong>und</strong> dieses Ergebnis in dem zusätzlich eingefügten<br />
Layer. Da „<strong>db4o</strong>“ in erster Linie für Java <strong>und</strong> .Net Entwicklern bereitgestellt wird, musste wie im<br />
Kapitel [5.2.1 Datenbanken] beschrieben, eine in .Net implementierte Klasse eingeb<strong>und</strong>en werden.<br />
Durch die Verwendung einer .Net-Klasse muss der Overhead der virtuellen Maschine <strong>von</strong> .Net in<br />
Kauf genommen werden.<br />
Abbildung 5-30: .Net-Basisprinzip [Wiki.Net]<br />
Um eine bessere Analyse zu erlauben werden die vier Plots nachfolgend ohne das DBMS „<strong>db4o</strong>“<br />
erneut dargestellt.<br />
Herbst 2011 21/36
Kapitel: 5 Benchmark<br />
Abbildung 5-31: Ergebnisse ohne "<strong>db4o</strong>"<br />
Die in der Abbildung [Abbildung 5-30: Ergebnisse ohne "<strong>db4o</strong>"] dargestellten Plots zeigen die<br />
Ergebnisse ohne das DBMS „<strong>db4o</strong>“. In diesen Plots kristallisiert sich nun die <strong>MongoDB</strong> heraus. Sie<br />
benötigt für die gestellten Anfragen erheblich länger als die SQL-Datenbanken. Die beiden DBMS<br />
<strong>PostgreSQL</strong> <strong>und</strong> <strong>SQLite</strong> weisen in den Plots ähnliche Zeiten auf.<br />
Herbst 2011 22/36
Kapitel: 5 Benchmark<br />
Zu beachten ist, dass <strong>PostgreSQL</strong> <strong>und</strong> <strong>SQLite</strong> relational DBMS sind im Gegensatz zur objektorientierten<br />
<strong>db4o</strong> <strong>und</strong> dokument-orientierter <strong>MongoDB</strong>. Deshalb ist es denkbar, dass gewisse<br />
DBMS je nach Art der Datenstruktur Vorteile in bestimmten Anwendungsgebiete besitzen.<br />
Durch den durchgeführten Benchmark können folgende Aussagen getroffen werden.<br />
• Das DMBS „<strong>db4o</strong>“ weisst im <strong>Vergleich</strong> zu den anderen drei DBMS die schlechteste<br />
Performanz auf. Wie bereits erwähnt, könnte der zusätzlich eingefügte Layer durch die .Net<br />
CLR für den starken Performanz-Verlust verantwortlich sein.<br />
• Interessant wäre nun wie sich die DBMS aus Java oder .Net verhalten würden. Denkbar<br />
wäre, dass <strong>db4o</strong> dadurch einen Vorteil erhalten würde. Dies darum, weil nun <strong>db4o</strong> in der für<br />
sie vorgesehenen Umgebung eingesetzt werden würde.<br />
• Beim <strong>Vergleich</strong> der DBMS ohne „<strong>db4o</strong>“ zeigt sich, dass die <strong>MongoDB</strong> bei den meisten Test<br />
schlecht abschneidet. Interessant sind jedoch die ähnliche Ergebnisse beim BMT-5 Join.<br />
Obwohl die <strong>MongoDB</strong> nicht für Join-Abfragen ausgerichtet ist, performt sie nicht<br />
wesentlich schlechter.<br />
• Es ist erstaunlich wie gut die noch sehr junge <strong>MongoDB</strong> mit dem ca. 30 Jährigen <strong>PostgreSQL</strong><br />
mithalten kann. Nun stellt sich die Frage, ob der neue, dokumentorientierte Ansatz in<br />
Zukunft ähnliche oder sogar bessere Leistungen erbringen wird <strong>und</strong> sich dadurch zum neuen<br />
Datenbankstandard durchsetzen kann.<br />
• Die relationalen Datenbanken <strong>SQLite</strong> <strong>und</strong> <strong>PostgreSQL</strong> weissen in den meisten Plots sehr<br />
ähnlich Werte auf. Dies lässt sich vermutlich auf die gemeinsame verwendete Technologie<br />
SQL zurückführen.<br />
Herbst 2011 23/36
Kapitel: 6 <strong>Vergleich</strong>barkeitsbasis & Optimierungspotentiale<br />
6<br />
<strong>Vergleich</strong>barkeitsbasis & Optimierungspotentiale<br />
Dieses Kapitel zeigt die Möglichkeiten auf, welche fairere <strong>Vergleich</strong>sbarkeitsbasis erlauben. Des<br />
Weitern werden auch Optimierungspotentiale aufgelistet.<br />
Zu beachten ist, dass die nachfolgend gezeigten Optimierungen lediglich eine kleine Menge der<br />
Möglichkeiten darstellen.<br />
6.1 Isolation-Level<br />
Durch die Verwendung der „Out-Of-The-Box“-Konfiguration der DBMS weisen diese zum Teil<br />
unterschiedliche Isolation-Level auf. Folgende Default-Einstellungen gelten für die DBMS.<br />
• <strong>PostgreSQL</strong>: Read-Commited [IsoLevelPostgres]<br />
• <strong>SQLite</strong>: Serialized [IsoLevel<strong>SQLite</strong>]<br />
• Db4o: Read-Commited [IsoLevelDb4o]<br />
• <strong>MongoDB</strong>: Kein Isolation-Level <strong>und</strong> ACID grössten Teils nicht umgesetzt [IsoLevelMongo]<br />
Um eine faire <strong>Vergleich</strong>barkeitsbasis zu schaffen, müssen die Isolation-Level entsprechend angepasst<br />
werden.<br />
6.2 Datentyp-Sicherheit<br />
Nicht jedes der vier getesteten DBMS gewährleistet Typsicherheit. So ist <strong>SQLite</strong> <strong>von</strong> sich aus nicht<br />
typsicher. Der Datentyp wird aus dem zu speicherndem Wert abgeleitet <strong>und</strong> nicht dessen Container.<br />
Ein mögliche Variante um eine faire <strong>Vergleich</strong>sbasis zu schaffen, liegt in dem manuellen Definieren<br />
<strong>von</strong> Check-Constraints wie im folgendem Beispiel gezeigt ist. [<strong>SQLite</strong>Type]<br />
ALTER TABLE raindrob ADD CONSTRAINT is_timestamp_int<br />
CHECK (timestamp BETWEEN 1000000000 and 9999999999)<br />
Abbildung 6-1: Erstellen <strong>von</strong> Check-Constraints<br />
6.3 Einsatz <strong>von</strong> Index<br />
Durch das Erstellen <strong>von</strong> Indexen kann eine bessere <strong>Performance</strong> bei den DBMS erzielt werden. Die<br />
Indexierung wird bei den vier betrachten Datenbanken unterstützt. Der nachfolgende Python-Code<br />
zeigt das Erstellen eines Index für die einzelnen DBMS.<br />
cursor.execute("CREATE INDEX time_idx ON raindrop(x, timestamp);")<br />
Abbildung 6-2: Erstellen eines Indexes für <strong>PostgreSQL</strong> <strong>und</strong> <strong>SQLite</strong><br />
Herbst 2011 24/36
Kapitel: 6 <strong>Vergleich</strong>barkeitsbasis & Optimierungspotentiale<br />
db.raindrop.ensure_index('timestamp')<br />
db.raindrop.ensure_index('x')<br />
Abbildung 6-3: Erstellen eines Indexes für <strong>MongoDB</strong><br />
Db4oFactory.Configure().ObjectClass(clr.GetClrType(Raindrop))<br />
.ObjectField("_x").Indexed("true")<br />
Db4oFactory.Configure().ObjectClass(clr.GetClrType(Raindrop))<br />
.ObjectField("_timestamp").Indexed("true")<br />
Abbildung 6-4: Erstellen eines Indexes für <strong>db4o</strong><br />
Wie die untenstehenden Plots aufzeigen, konnte durch das Verwenden <strong>von</strong> Index-Strukturen über<br />
die Spalten „x“ <strong>und</strong> „timestamp“ teilweise signifikante Verbesserungen erreicht werden.<br />
In jedem Plot sind auf der X-Achse die sechs nacheinander durchgeführten Benchmarks. Die Y-<br />
Achse zeigt die jeweilige Dauer in Sek<strong>und</strong>en. Folgende Legende gilt für die untenstehenden<br />
Diagramme.<br />
<strong>SQLite</strong><br />
<strong>PostgreSQL</strong><br />
<strong>db4o</strong><br />
<strong>MongoDB</strong><br />
Abbildung 6-5: Ergebnisse mit Index-Strukturen<br />
Herbst 2011 25/36
Kapitel: 7 Schlussfolgerung<br />
7<br />
Schlussfolgerung<br />
Das Schaffen einer fairen <strong>Vergleich</strong>barkeitsbasis stellte sich als anspruchsvoller heraus als erwartet.<br />
Durch die Verwendung der zum Teil sehr unterschiedlichen DBMS war das Finden eines<br />
gemeinsamen Nenners sehr schwierig. Darum entschieden wir uns für die Durchführung des<br />
Benchmarks mit den Default-Einstellungen der jeweiligen DBMS. Erst in einem zweiten Schritt<br />
wurden bestimmte Ansätze aufgezeigt, wie eine faire <strong>Vergleich</strong>barkeitsbasis aufgebaut werden<br />
könnte (siehe Kapitel [6 <strong>Vergleich</strong>barkeitsbasis & Optimierungspotentiale]).<br />
Bei der Wahl eines DBMS ist nebst der <strong>Performance</strong> auch das darunterliegende Konzept eines<br />
DBMS zu beachten. Je nach Daten bzw. Verwendungszwecken eignet sich ein anderes Konzept<br />
besser. D.h. nebst dem stark verbreiteten Konzept der relationalen DBMS soll auch die neue Art der<br />
nicht-relationalen bzw. NoSQL-DBMS in die Evaluation miteinbezogen werden. Jedoch erfordert<br />
der Entscheid für ein NoSQL-DBMS eine andere Denkweise.<br />
Durch das Datenbankseminar konnte Einblick in verschiedene DBMS gewonnen werden. Zusätzlich<br />
konnten Erfahrungen in der Skriptsprach „Python“ gesammelt werden.<br />
Herbst 2011 26/36
Kapitel: 8 Eigenständigkeitserklärung<br />
8<br />
Eigenständigkeitserklärung<br />
Wir, Philippe Morier <strong>und</strong> Martin Weber erklären hiermit,<br />
- dass wir die vorliegende Arbeit selber <strong>und</strong> ohne fremde Hilfe durchgeführt haben, ausser<br />
derjenigen, welche explizit in der Aufgabenstellung erwähnt ist oder mit dem Betreuer schriftlich<br />
vereinbart wurde,<br />
- dass wir sämtliche verwendeten Quellen erwähnt <strong>und</strong> gemäss gängigen wissenschaftlichen<br />
Zitierregeln korrekt angegeben haben.<br />
Rapperswil, 23. Dezember 2011<br />
Philippe Morier<br />
Martin Weber<br />
Herbst 2011 27/36
Kapitel: 9 Glossar<br />
9<br />
Glossar<br />
ACID<br />
ANSI<br />
BMT<br />
BSON<br />
CLR<br />
CPU<br />
DBMS<br />
EDV<br />
GIF<br />
GiST<br />
JSON<br />
NoSQL<br />
NZZ<br />
ORDBMS<br />
RAM<br />
RDBMS<br />
SQL<br />
Atomicity, Consistency, Isolation <strong>und</strong> Durability<br />
American National Standards Institute<br />
Benchmark Test<br />
Binary JSON<br />
Common Language Runtime<br />
Central Processing Unit<br />
Datenbankmanagementsystem<br />
Elektronische Datenverarbeitung<br />
Graphics Interchange Format<br />
Generalized Search Tree<br />
JavaScript Object Notation<br />
Not only SQL<br />
Neue Zürcher Zeitung<br />
Objektrelationales DBMS<br />
Random-Access-Memory<br />
Relationales DBMS<br />
Structured Query Language<br />
Herbst 2011 28/36
Kapitel: 10 Abbildungsverzeichnis<br />
10 Abbildungsverzeichnis<br />
Abbildung 4-1: Niederschlagsradar <strong>von</strong> NZZ Online .................................................................................. 9<br />
Abbildung 4-2: Extraktion der Niederschlag-Pixel ....................................................................................... 9<br />
Abbildung 4-3: Einzelner Niederschlags-Pixel .............................................................................................. 10<br />
Abbildung 5-1: Aufbau des Benchmarks ..........................................................................................................11<br />
Abbildung 5-2: Inhalt der Datei „_start_<strong>db4o</strong>.bat“...................................................................................... 12<br />
Abbildung 5-3: Ausführung des Benchmarks mit entsprechenden Parameter ......................................... 13<br />
Abbildung 5-4: Struktur der Tabelle "raindrop"............................................................................................ 13<br />
Abbildung 5-5: Fehler beim Abspeichern [IrPyObj]..................................................................................... 13<br />
Abbildung 5-6: Klasse "raindrop"..................................................................................................................... 14<br />
Abbildung 5-7: "raindrop"-Dokument............................................................................................................. 14<br />
Abbildung 5-8: Struktogramm des Ablaufs .................................................................................................... 15<br />
Abbildung 5-9: Einfügen der Test-Daten in "<strong>PostgreSQL</strong>".......................................................................... 16<br />
Abbildung 5-10: Einfügen der Test-Daten in "<strong>SQLite</strong>" ................................................................................. 16<br />
Abbildung 5-11: Einfügen der Test-Daten in "<strong>db4o</strong>" ..................................................................................... 16<br />
Abbildung 5-12: Einfügen der Test-Daten in "<strong>MongoDB</strong>" ........................................................................... 16<br />
Abbildung 5-13: Abfragen aller Test-Daten in "<strong>PostgreSQL</strong>" <strong>und</strong> „<strong>SQLite</strong>“............................................. 17<br />
Abbildung 5-14: Abfragen aller Test-Daten in "<strong>db4o</strong>".................................................................................. 17<br />
Abbildung 5-15: Abfragen aller Test-Daten in "<strong>MongoDB</strong>"......................................................................... 17<br />
Abbildung 5-16: Abfragen der Test-Daten auf x-Koordinate 200 in "<strong>PostgreSQL</strong>"................................. 17<br />
Abbildung 5-17: Abfragen der Test-Daten auf x-Koordinate 200 in "<strong>SQLite</strong>".......................................... 17<br />
Abbildung 5-18: Abfragen der Test-Daten auf x-Koordinate 200 in "<strong>db4o</strong>" ............................................. 17<br />
Abbildung 5-19: Abfragen der Test-Daten auf x-Koordinate 200 in "<strong>MongoDB</strong>" ................................... 17<br />
Abbildung 5-20: Betroffene Regionen ............................................................................................................. 18<br />
Abbildung 5-21: Abfragen der Test-Daten auf einen Bereich in "<strong>PostgreSQL</strong>"......................................... 18<br />
Abbildung 5-22: Abfragen der Test-Daten auf einen Bereich in "<strong>SQLite</strong>" ................................................. 18<br />
Abbildung 5-23: Abfragen der Test-Daten auf einen Bereich in "<strong>db4o</strong>"..................................................... 18<br />
Abbildung 5-24: Abfragen der Test-Daten auf einen Bereich in "<strong>MongoDB</strong>" .......................................... 18<br />
Abbildung 5-25: Join-Abfragen in "<strong>PostgreSQL</strong>" ........................................................................................... 18<br />
Abbildung 5-26: Join-Abfragen in "<strong>SQLite</strong>" ................................................................................................... 18<br />
Abbildung 5-27: Join-Abfragen in "<strong>db4o</strong>" ....................................................................................................... 19<br />
Abbildung 5-28: Join-Abfragen "<strong>MongoDB</strong>" .................................................................................................. 19<br />
Abbildung 5-29: Ergebnisse des Benchmarks ................................................................................................ 20<br />
Abbildung 5-30: .Net-Basisprinzip [Wiki.Net].............................................................................................. 21<br />
Abbildung 5-31: Ergebnisse ohne "<strong>db4o</strong>" ......................................................................................................... 22<br />
Herbst 2011 29/36
Kapitel: 10 Abbildungsverzeichnis<br />
Abbildung 6-1: Erstellen <strong>von</strong> Check-Constraints ......................................................................................... 24<br />
Abbildung 6-2: Erstellen eines Indexes für <strong>PostgreSQL</strong> <strong>und</strong> <strong>SQLite</strong> ........................................................ 24<br />
Abbildung 6-3: Erstellen eines Indexes für <strong>MongoDB</strong> ................................................................................. 25<br />
Abbildung 6-4: Erstellen eines Indexes für <strong>db4o</strong> .......................................................................................... 25<br />
Abbildung 6-5: Ergebnisse mit Index-Strukturen ......................................................................................... 25<br />
Herbst 2011 30/36
Kapitel: 11 Tabellenverzeichnis<br />
11<br />
Tabellenverzeichnis<br />
Tabelle 3-1: Limits <strong>von</strong> <strong>PostgreSQL</strong> [Postgres] ................................................................................................7<br />
Tabelle 3-2: Limits <strong>von</strong> <strong>SQLite</strong> [SQLimits] ......................................................................................................7<br />
Tabelle 3-3: Philosophie <strong>von</strong> <strong>MongoDB</strong> .......................................................................................................... 8<br />
Tabelle 5-1: Aufbau der Tabelle "raindrop" mit Beispiel Datensätze .......................................................... 13<br />
Tabelle 5-2: Systemeigenschaften ..................................................................................................................... 19<br />
Herbst 2011 31/36
Kapitel: 12 Literaturverzeichnis<br />
12<br />
Literaturverzeichnis<br />
[Cattell]<br />
The Engineering Database Benchmark,<br />
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.89.1518&rep=rep1&typ<br />
e=pdf,<br />
aufgerufen am 19.12.2011<br />
[<strong>db4o</strong>]<br />
<strong>db4o</strong> :: Java & .NET Object Database :: Product Information,<br />
http://www.<strong>db4o</strong>.com/about/productinformation/,<br />
http://www.<strong>db4o</strong>.com/about/productinformation/datasheet/,<br />
aufgerufen am 20.10.11<br />
[FAME]<br />
Fame Database <strong>Performance</strong> Benchmark for Time Series Data,<br />
http://www.scribd.com/doc/53366489/Fame-WhitePaper-FameBenchmarking,<br />
aufgerufen am 19.12.2011<br />
[IrPyObj]<br />
How to store objects created in IronPython to object databases - Stack<br />
[IsoLevelDb4o]<br />
Isolation Level For Db4o,<br />
Overflow,<br />
http://stackoverflow.com/questions/2352718/how-to-store-objects-created-inironpython-to-object-databases,<br />
aufgerufen am 01.11.11<br />
http://dz.prosyst.com/user-manuals/mBS_Extensions_6.1.5/database/<strong>db4o</strong>-6.3-<br />
doc/reference/html/reference/basic_concepts/acid_model/isolation_level_for_<br />
<strong>db4o</strong>.html,<br />
aufgerufen am 05.12.11<br />
[IsoLevelMongo]<br />
database - Why doesn't <strong>MongoDB</strong> use fsync()? - Stack Overflow,<br />
http://stackoverflow.com/questions/3736533/why-doesnt-mongodb-use-fsync,<br />
two-phase commit – <strong>MongoDB</strong>,<br />
http://www.mongodb.org/display/DOCS/two-phase+commit,<br />
aufgerufen am 05.12.11<br />
[IsoLevelPostgres]<br />
<strong>PostgreSQL</strong>: Documentation: Manuals: Transaction Isolation,<br />
http://www.postgresql.org/docs/8.1/static/transaction-iso.html,<br />
aufgerufen am 05.12.11<br />
[IsoLevel<strong>SQLite</strong>]<br />
<strong>SQLite</strong> Shared-Cache Mode,<br />
http://www.sqlite.org/sharedcache.html,<br />
aufgerufen am 05.12.11<br />
[MemoryError]<br />
6. Built-in Exceptions - Python v2.7.2 documentation,<br />
Herbst 2011 32/36
Kapitel: 12 Literaturverzeichnis<br />
http://docs.python.org/library/exceptions.html#exceptions.MemoryError,<br />
aufgerufen am 11.11.11<br />
[<strong>MongoDB</strong>]<br />
Philosophy – <strong>MongoDB</strong>,<br />
http://www.mongodb.org/display/DOCS/Philosophy,<br />
http://blog.mongodb.org/post/137788967/32-bit-limitations,<br />
aufgerufen am 20.10.11<br />
[MOtt] Key/Value Pair Versus hstore - Benchmarking Entity-Attribute-Value<br />
Structures in <strong>PostgreSQL</strong>,<br />
http://wiki.hsr.ch/Datenbanken/files/Benchmark_of_KVP_vs._hstore_-<br />
_doc.pdf,<br />
http://wiki.hsr.ch/Datenbanken/files/db-benchmark_mott.zip,<br />
aufgerufen am 16.01.12<br />
[Niall] <strong>MongoDB</strong> and Python, Niall O’Higgins, O’Reilly, 2011,<br />
ISBN: 978-1-449-31037-0<br />
[NZZ]<br />
Animierte Bildserie (Wetter, NZZ Online),<br />
http://www.nzz.ch/nachrichten/wetter/radarbild_animierte_serie_1.134.html,<br />
aufgerufen am 29.09.11<br />
[OxfordJournals]<br />
A Practitioner's Introduction to Database <strong>Performance</strong> Benchmarks and<br />
Measurements,<br />
http://comjnl.oxfordjournals.org/content/35/4/322.full.pdf,<br />
aufgerufen am 05.12.2011<br />
[PolePosition]<br />
PolePosition Open Source Database Benchmark,<br />
http://www.polepos.org/,<br />
aufgerufen am 19.12.2011<br />
[Postgres]<br />
<strong>PostgreSQL</strong>: About,<br />
http://www.postgresql.org/about/,<br />
aufgerufen am 20.10.11<br />
[PostgresDE]<br />
<strong>PostgreSQL</strong> im Schnelldurchgang,<br />
http://www.postgres.de/postgresql_outline.html,<br />
aufgerufen am 20.10.11<br />
[PyMongo]<br />
PyMongo 2.0.1 Documentation - PyMongo v2.0.1 documentation,<br />
http://api.mongodb.org/python/current/,<br />
aufgerufen am 20.10.11<br />
[SQLimits]<br />
Implementation Limits For <strong>SQLite</strong>,<br />
http://www.sqlite.org/limits.html,<br />
aufgerufen am 20.10.11<br />
Herbst 2011 33/36
Kapitel: 12 Literaturverzeichnis<br />
[<strong>SQLite</strong>]<br />
About <strong>SQLite</strong>,<br />
http://www.sqlite.org/about.html,<br />
aufgerufen am 20.10.11<br />
[<strong>SQLite</strong>Type]<br />
Typsicherheit <strong>von</strong> <strong>SQLite</strong>,<br />
http://www.sqlite.org/datatype3.html,<br />
http://commitsuicide.wordpress.com/2008/09/11/sqlite-ein-ziemlich-nettesembedded-dms/,<br />
aufgerufen am 05.12.11<br />
[TexasBench]<br />
HSR Texas Geo Database Benchmark – GISpunkt HSR,<br />
http://www.gis.hsr.ch/wiki/HSR_Texas_Geo_Database_Benchmark<br />
aufgerufen am 31.10.11<br />
[TPC]<br />
TPC - Benchmarks,<br />
http://www.tpc.org/information/benchmarks.asp,<br />
aufgerufen am 19.12.2011<br />
[Wiki.Net]<br />
Datei:Net Basisprinzip ext.svg – Wikipedia,<br />
http://de.wikipedia.org/w/index.php?title=Datei:Net_Basisprinzip_ext.svg&file<br />
timestamp=20080115070326,<br />
aufgerufen am 05.12.11<br />
[Wiki<strong>SQLite</strong>]<br />
<strong>SQLite</strong> – Wikipedia,<br />
http://de.wikipedia.org/wiki/Sqlite,<br />
aufgerufen am 20.10.11<br />
Herbst 2011 34/36
Kapitel: 13 Code der Datei „benchmark.py“<br />
13<br />
Code der Datei „benchmark.py“<br />
Herbst 2011 35/36
Kapitel: 13 Code der Datei „benchmark.py“<br />
Herbst 2011 36/36