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