<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Minimal-Invasive Indexintegration</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Transparente Datenbankbeschleunigung</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
          <xref ref-type="aff" rid="aff2">2</xref>
          <xref ref-type="aff" rid="aff3">3</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Alexander Adam dimensio informatics GmbH Brückenstraße 4 09111 Chemnitz</institution>
        </aff>
        <aff id="aff1">
          <label>1</label>
          <institution>Datenbankenerweiterung</institution>
          ,
          <addr-line>Indizierung, Transparent</addr-line>
        </aff>
        <aff id="aff2">
          <label>2</label>
          <institution>Sebastian Leuoth dimensio informatics GmbH Brückenstraße 4 09111 Chemnitz</institution>
        </aff>
        <aff id="aff3">
          <label>3</label>
          <institution>Wolfgang Benn Technische Universität Chemnitz Straße der Nationen 62 09107 Chemnitz</institution>
        </aff>
      </contrib-group>
      <pub-date>
        <year>2012</year>
      </pub-date>
      <abstract>
        <p>Datenbanksysteme haben in den letzten Jahrzehnten ein breites Anwendungsspektrum erschlossen. Funktionalitäten wurden oft aufgrund der Bedürfnisse der Anwender hinzugefügt [17]. So gibt es heute nutzerdefinierte Datentypen, nutzerdefinierte Datenablagen und selbst elementare Dinge wie Indexe, die durch einen Nutzer in ihrer Struktur bestimmt werden. Allen gemein ist eine gewisse Abhängigkeit der Implementation vom Datenbankhersteller und einer damit verbundenen schlechten Portabilität der entwickelten Module. Besonders im Bereich der Indizierung um den es in diesem Papier gehen soll, stellen sich aber noch weitere Probleme dar. Normalerweise kann ein Index auf einer beliebigen Tabelle und deren Spalten definiert werden. Die Anwendung bemerkt nur insoweit etwas von dieser Aktion, als dass Anfragen schneller beantwortet werden sollten. Ein kleines Beispiel soll dies verdeutlichen. Die folgende Anfrage gibt alle Mitarbeiterinformationen zurück, die zu Mitarbeitern mit mehr als 1000 Euro Gehalt gehören:</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>ZUSAMMENFASSUNG</title>
      <p>
        Aktuelle Datenbanksysteme bieten dem Nutzer eine
enorme Funktionsvielfalt [
        <xref ref-type="bibr" rid="ref12 ref8">12, 8</xref>
        ]. Selbst sehr spezielle Gebiete
wie z. B. Geodatentypen [
        <xref ref-type="bibr" rid="ref14 ref9">9, 14</xref>
        ] werden unterstützt.
Abhängig vom verwendeten Datenbanksystem können diese
Fähigkeiten durch einen Nutzer noch erweitert werden.
Beispiele hierfür wären Funktionen und nutzerdefinierte
Datentypen [
        <xref ref-type="bibr" rid="ref12 ref8">12, 8</xref>
        ]. Alle diese Erweiterungen sollten
natürlich nicht die Geschwindigkeit des Datenbanksystems
negativ beeinflussen. So gibt es neben normalen Indexen auch
Funktionsindexe und Indexe für nutzerdefinierte
Datenhaltungen [
        <xref ref-type="bibr" rid="ref2 ref20">20, 2</xref>
        ]. Die Möglichkeiten, zu indizieren sind dabei, je
nach Datenbankhersteller, vorbestimmt und selbst nicht
erweiterbar. Allen diesen Techniken ist weiterhin gemein, dass
sie direkt am Datenbanksystem ansetzen und teils auch in
der Anfragesprache sichtbar sind. Es ist daher nicht einfach
möglich, eine Anwendung, die fest vorgegeben ist, mittels
solcher Techniken zu beschleunigen. In diesem Papier
wollen wir eine Möglichkeit vorstellen, mit der eine solche
Beschleunigung auch dann noch möglich ist, wenn weder das
Datenbanksystem noch die Anwendung im Zugriff des
Nutzers stehen. Verdeutlicht wird dieses am Beispiel der
JDBCSchnittstelle [
        <xref ref-type="bibr" rid="ref15">15</xref>
        ].
      </p>
    </sec>
    <sec id="sec-2">
      <title>EINLEITUNG</title>
      <p>Listing 1: SQL-Anfrage mit Bedingung im WHERE-Teil
SELECT ∗
FROM mitarb</p>
      <p>WHERE mitarb.gehalt &gt; 1000
Für die Anwendung, die diese Anfrage an die Datenbank
stellt, ist es vollkommen unerheblich, ob sich auf der
Gehaltsspalte der Mitarbeitertabelle ein Index befindet oder
nicht. Die Anfrage würde, ob nun mit oder ohne Index,
immer gleich aussehen.</p>
      <p>Wir nehmen nun an, dass die Gehaltsspalte durch einen
anderen Typ ersetzt werden soll, Gründe hierfür könnten
eine effizientere Speicherung oder bessere
Zugriffsmöglichkeiten sein. Wir nehmen weiter an, dass das Datenbanksystem
für den neuen Typ den &gt;-Operator nicht mehr anbietet. Es
muss nun eine Vergleichsfunktion geschrieben werden, die
die Aufgabe des &gt;-Operators übernimmt. Diese
tiefgreifende Umstrukturierung scheint nun bis in die Anfrage durch,
ist also nicht mehr transparent:
Listing 2: SQL-Anfrage mit Anfrage an eine
nutzerdefinierte Funktion im WHERE-Teil</p>
      <p>SELECT ∗
FROM mitarb</p>
      <p>WHERE pruefe( mitarb.gehalt, 1000) = 1
Eine Anwendung, die der Nutzer nicht verändern kann,
würde also von diesem neuen Typ ausschließlich dann
profitieren, wenn der Hersteller diese Möglichkeit vorsieht oder
standardmäßig einbaut. Für bestehende Umgebungen ist all
dies also keine Option.</p>
      <p>
        Im obigen Fall würde noch die Möglichkeit des
automatischen SQL-Umschreibens einen Ausweg bieten [
        <xref ref-type="bibr" rid="ref12 ref8">12, 8</xref>
        ]. Dabei
wird eine materialisierte Sicht angelegt. Anschließend wird
der Datenbank mitgeteilt, dass bestimmte Anfragen nicht so
gestellt werden sollen, wie sie der Anwender abgesetzt hatte,
sondern in veränderter Form auf der materialisierten Sicht
abgearbeitet werden. Das Vorgehen muss vom
Datenbanksystem aber auch unterstützt werden. Je nach Ausprägung
müssen außerdem genaue Übereinstimmungsmerkmale
angegeben werden, mit denen das Umschreiben ausgelöst wird.
Scheitert das Umschreiben, weil es eine kleine Varianz in der
Anfrage gibt, wird das Ergebnis u. U. falsch.
      </p>
      <p>Im Folgenden werden wir eine Möglichkeit aufzeigen, wie
es ohne einen Eingriff – weder bei der Anwendung noch
bei der Datenbank – möglich ist, einen Index weitestgehend
transparent in ein bestehendes System zu integrieren.
Dazu wird zunächst untersucht, an welchen Stellen und wie in
die Kommunikation von Anwendung und Datenbanksystem
eingegriffen werden kann. Anschließend wird auf die
Herausforderungen eingegangen, die sich bei dem hier genutzten
Ansatz zeigen und wie diese gelöst werden können.</p>
    </sec>
    <sec id="sec-3">
      <title>2. INTEGRATIONSPUNKTE 2.1 Überblick</title>
      <p>Um mögliche Integrationspunkte zu finden, muss zunächst
untersucht werden, wie eine Anwendung mit einem
Datenbanksystem kommuniziert. Üblicherweise werden hierfür
Datenbanktreiber eingesetzt. Das sind Programmbibliotheken,
die die Anfragen in ein dem Datenbanksystem
verständliches Protokoll überführen und dieses dann übermitteln. Der
Datenbankserver dekodiert das Protokoll und arbeitet die
darin enthaltenen Anweisungen ab.</p>
      <p>
        Im Folgenden werden wir uns auf den Datenbanktreiber,
also die Anwendungsseite, konzentrieren. Die Vorgehensweise
bei der Integration in die Kommuniktion ist bereits in [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ]
beschrieben. Möglichkeiten, ein Datenbanksystem zu
erweitern, wurden in den letzten Jahrzehnten vielfach an anderer
Stelle beschrieben [
        <xref ref-type="bibr" rid="ref2 ref20 ref4">4, 20, 2</xref>
        ].
2.2
      </p>
    </sec>
    <sec id="sec-4">
      <title>Datenbanktreiber</title>
      <p>
        Der Datenbanktreiber ist die Schnittstelle für einen
Anwendungsprogrammierer, um mit dem Datenbanksystem zu
kommunizieren. Er stellt Funktionen bereit, um
Verbindungen zu verwalten und Datenbankanfragen abzuarbeiten (sei
es nun SQL oder irgendeine andere Art der Anfrage) [
        <xref ref-type="bibr" rid="ref11 ref5">5,
11</xref>
        ]. Es ist wichtig, zu beobachten, dass dabei jeder
Abarbeitungsschritt von der Anwendung ausgelöst wird. Alle
Ergebnisse einer Anfrage werden nicht einfach als Resultat
einer query()-Funktion zurückgegeben, sondern müssen
aktiv angefordert werden. Eine typische Schrittfolge, die eine
Anwendung verwenden könnte, ist in Listing 3 aufgezeigt.
Listing 3: Mögliche, stark reduzierte, Schrittfolge
bei der Nutzung einer Datenbankbibliothek, hier
JDBC. Es wird zunächst eine Verbindung geöffnet,
dann ein Statement mit ungebundenen Variablen
vorbereitet und gebunden. Schließlich werden die
angefragten Daten abgeholt.
      </p>
      <p>Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost/testdb",
"username",
"password");
Statement ps = conn.prepareStatement(
"SELECT ∗ FROM mitarb</p>
      <p>WHERE gehalt &gt; ?");
ps. setInt (1, 1000);
ResultSet rs = ps.executeQuery();
String name = rs.getString("name");
ps. close () ;
conn.close () ;</p>
      <p>Wie nun stellt sich hier eine Möglichkeit zur Integration
dar? Es ist möglich, vor jede Funktion, die eine Anwendung
vom originalen Datenbanktreiber aufruft, eine eigene
Funktion zu setzen. Die Anwendung ruft nun die eigene
Funktion, ohne dies zu bemerken, und die eigene Funktion ruft
schließlich die originale. Da nun alle Daten, die von einer
Anwendung zum Datenbanksystem gesendet werden, vorher
analysiert und verändert werden können, stellt sich so dieser
Integrationspunkt dar. Außerdem können eigene Funktionen
auf der so abgefangenen Datenbankverbindung „huckepack“
aufgesetzt werden.</p>
      <p>
        Ein erster Gedanke, dies zu realisieren, könnte in die
Richtung einer DLL-Injection [
        <xref ref-type="bibr" rid="ref18">18</xref>
        ] gehen. Das bedeutet das
komplette Ersetzen des vom Datenbankhersteller
bereitgestellten Treibers durch einen eigenen. Dieser kann, da die
Protokolle nicht zwingend offengelegt sein müssen, die
Kommunikation mit dem Datenbanksystem nicht selbst übernehmen,
sondern ruft den ursprünglichen Datenbanktreiber.
Abhängig von der Anzahl der zu implementierenden Funktionen
kann dies ein möglicher Weg sein. Eine weit verbreitete
solche Schnittstelle, um aus einer Javaanwendung mit einem
Datenbanksystem in Verbindung zu treten, ist JDBC. Mit
seinen vielen Klassen und mehr als 1000 zugehörigen
Methoden [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ] wäre es eine sehr langwierige Aufgabe, einen
solchen sogenannten Wrapper [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ] zu implementieren. In einem
unserer Produkte namens Cardigo ist dieses aber bereits
implementiert und erleichtert so die Aufgabe enorm. Weitere
Projekte und Arbeiten zu diesem Thema sind unter anderem
auch bei [
        <xref ref-type="bibr" rid="ref19 ref21 ref22">19, 22, 21</xref>
        ] und [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ] zu finden.
      </p>
      <p>Cardigo ist ein Rahmenwerk, welches u. a. alle Klassen
und Methoden enthält, die das JDBC-API anbietet.
Anstatt selbst ein kompletter Treiber zu sein, bietet es lediglich
einen Wrapper für einen „richtigen“ Datenbanktreiber. Das
Ziel dieses Produktes ist es, einem Anwender die Möglichkeit
zu geben, die Datenbankkommunikation – in diesem Falle
hauptsächlich Anfragen, Ergebnisse u. s. w. – zu loggen oder
gar zu verändern. Mit diesem Werkzeug können wir nun die
Integration des Index angehen.</p>
      <p>Technisch ist zur Integration von Cardigo nichts weiter
nötig, als ein geänderter Verbindungsparameter für die
Anwendung. Dieser bewirkt, dass anstelle des originalen
JDBCTreibers nun Cardigo geladen wird. Der Aufbau dieser
veränderten Umgebung ist in Abbildung 2 verdeutlicht.</p>
    </sec>
    <sec id="sec-5">
      <title>3. INTEGRATION</title>
      <p>
        Bevor wir die Integration des Index weiter betrachten,
wollen wir kurz darauf eingehen, wie ein in ein
Datenbanksystem integrierter Index arbeitet: Wird eine Anfrage an die
Datenbank gestellt und treffen einige der verwendeten
Attribute die im Index enthaltenen, so wird der Index
verwendet. Dabei wird die Anfrage vom Index bearbeitet und im
Ergebnis entsteht einen Liste von Ergebniskandidaten.
Diese können in Form von RowIDs [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ] oder auch einfach als
Primärschlüssel vorliegen. Das Datenbanksystem überprüft
dann nur noch die Datensätze, deren Identifikatoren der
Index als Ergebnis lieferte. Auf diese Art wird der Aufwand,
den das Datenbanksystem beim Laden der Datensätze und
ihrer Verifikation hat, erheblich verringert [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ].
      </p>
      <p>Im Folgenden wird zunächst die logische Integration
betrachtet, d. h., wie es überhaupt möglich ist, Ergebnisse eines
Index an das Datenbanksystem zu übertragen. Es schließt
sich eine Betrachtung an, die die programmtechnische
Integration betrachtet, da sich hier noch einige weitere Probleme
auftun.
3.1</p>
    </sec>
    <sec id="sec-6">
      <title>Logische Integration</title>
      <p>Die Grundidee der Integration ist es nun, die Anfrage, die
eine Anwendung absetzt, so zu verändern, dass sie das
Verhalten eines datenbankinternen Index nachahmt. Die
Anfrage aus Listing 1 könnte nun, wie in Listing 4 aufgezeigt, um
das Primärschlüsselattribut erweitert werden.</p>
      <p>Listing 4: SQL-Anfrage, die um die Ergebnisse eines
externen Index erweitert wurde</p>
      <p>SELECT ∗
FROM mitarb
WHERE gehalt &gt; 2000</p>
      <p>AND id IN (4, 18)</p>
      <p>Dieses Vorgehen vertraut darauf, dass der Optimierer des
Datenbanksystems erkennt, dass es sich bei den Werten in
der IN-Klausel um Primärschlüssel handelt. Er muss diese
möglichst am Anfang der Anfrageverarbeitung einbeziehen,
um die Menge der zu untersuchenden Tupel zu minimieren.</p>
      <p>
        Durch Tests haben wir herausgefunden, dass die Anzahl
der in IN-Listen enthaltenen Elemente eine Obergrenze hat.
Durch die Disjunktion mehrerer IN-Listen kann diese zu
einem gewissen Grad ausgeglichen werden. Somit ist es
möglich, sehr lange Anfragen zu erzeugen, Allerdings gibt es auch
eine Grenze für die maximale, vom Datenbanksystem
zugelassene, Anfragelänge. Bei IBM DB2 und Oracle ist diese
Maximallänge bspw. 64kB [
        <xref ref-type="bibr" rid="ref16 ref8">8, 16</xref>
        ].
      </p>
      <p>Ein weiterer Aspekt, der bei diesen langen Anfragen
betrachtet werden muss, ist, dass diese vom Datenbanksystem
auch geparst werden. Werden die Anfragen lang, so
steigen auch deren Parsezeiten, selbst optimistisch betrachtet
ist dieser Zusammenhang linear. Auch systematisch bedingt,
ist, dass der Optimierer zu lange und viele IN-Listen nicht
beachtet, selbst wenn es sich um Primärschlüssel handelt.
Mit Hinweisen an den Optimierer kann hier gegengesteuert
werden. Zusammenfassend lässt sich aber sagen, dass ab
einer gewissen Anfragelänge, der Gewinn durch den Index sich
im schlechtesten Falle sogar ins Gegenteil verkehren kann.</p>
      <p>Um diese Beschränkungen zu umgehen, können die
Ergebnisse des Index auch in eine Tabelle in der Datenbank
eingefügt werden. Hier gibt es wieder mehrere
Möglichkeiten:</p>
      <sec id="sec-6-1">
        <title>1. Einfügen in eine Tabelle, die angelegt ist</title>
      </sec>
      <sec id="sec-6-2">
        <title>2. Einfügen in eine temporäre Tabelle</title>
        <p>In beiden Fällen muss allerdings die Datenbank in der
Weise modifiziert werden, dass die Anwendung, in die der
Index integriert wurde, das Recht hat, auf diese Tabellen zu
schreiben. Die Tabellen müssen prinzipiell eine Spalte für
die Anfrage und eine Spalte für die Ergebnisse des Index
besitzen.</p>
        <p>Werden über eine Sitzung Anfragen nur sequenziell
bearbeitet, haben temporäre Tabellen den Vorteil, dass
zwischen verschiedenen Datenbanksitzungen nicht mittels der
eben beschriebenen zusätzlichen AnfrageID-Spalte in dieser
Tabelle unterschieden werden muss. Das ist darin
begründet, dass temporäre Tabellen für jede Sitzung als leere neue
Tabellen erscheinen. Die Aktionen einer Sitzung wirken sich
nicht auf den Inhalt der temporären Tabelle in einer anderen
Sitzung aus.</p>
        <p>Ein bisher nicht zur Sprache gekommener Punkt ist das
Aktualisieren des Index. Natürlich muss ein
datenbankexterner Index über INSERT-, UPDATE- und DELETE-Operationen
informiert werden. Der einfachste Weg ist, wenn alle
Operationen, die auf der Datenbank laufen, über die gleiche
abgefangene Schnittstelle gehen und so direkt gelesen werden
können. In der Realität ist dies jedoch unpraktisch, da
diese Voraussetzung nicht zu 100% gewährleistet werden kann.
Trigger sind eine Variante, wie Veränderungen in der
Datenbank nach außen gereicht werden können, diese müssen
jedoch integriert werden dürfen. Hier ergeben sich damit auch
Grenzen, über die hinaus unser Ansatz nicht angewendet
werden kann. Eine andere Möglichkeit sind statische
Datenhaltungen, die nur in definierten Zeitabschnitten aktualisiert
werden, bspw. einmal pro Monat. Hier kann ein statischer
Index genutzt werden, der über eine simple Zeitsteuerung
aktualisiert wird.
3.2</p>
      </sec>
    </sec>
    <sec id="sec-7">
      <title>Programmtechnische Integration</title>
      <p>Oft halten sich Anwendungsprogrammierer an die Beispiele
der Autoren der jeweiligen Datenbankschnittstelle. Jedoch
erlauben alle APIs auch eine freiere Nutzung, d. h., dass die
Schrittfolge der Kommandos nicht festgelegt ist und es
verschiedene Gründe geben kann, die so aufgezeigten
Standardroutinen zu verwerfen. Listing 3 zeigt zunächst einen
Standardweg auf. Für diesen wollen wir nun die Schritte, die ein
datenbankexterner Index verfolgen kann, aufzeigen:
• Statement vorbereiten (conn.prepareStatement(...)):
if Anfrage relevant then</p>
      <p>Anfrage speichern
end if
• Variablen binden (ps.setInt(...)):
if Anfrage war relevant then</p>
      <p>Bindung speichern
end if
• Statement ausführen (ps.executeQuery()):
if Anfrage war relevant then</p>
      <p>Index anfragen
Indexergebnisse in DB laden
Anfrage modifizieren</p>
      <p>Datenbank anfragen
end if
• Ergebnisse holen (rs.getString(...)):</p>
      <p>hier sind keine weiteren Schritte notwendig</p>
      <p>Beobachtungen an realen Programmen zeigen, dass das
Binden von Variablen teils mehrfach auf die gleichen
Variablen angewendet wird. Mit dem eben beschriebenen
Verfahren ist dies kein Problem. Auch Operationen, die ein
Statement näher beschreiben, sind nach wie vor ausführbar, da
alle Bestandteile erhalten bleiben und nur Ergänzungen
vorgenommen werden.
4.</p>
    </sec>
    <sec id="sec-8">
      <title>ERGEBNISSE UND AUSBLICK</title>
      <p>Das hier beschriebene System war bereits erfolgreich im
Einsatz. Die Latenzen für das reine Abfangen der
Datenbankaufrufe bewegen sich im einstelligen Mikrosekundenbereich,
also dem, was für einen Funktionsaufruf erwartet werden
kann. Hinzu kommt die Zeit für die Indexanfrage. Für einen
realen Gewinn muss natürlich die Zeit für die
Integration, die Indexanfrage und den Einbau der Ergebnisse in das
Statement in Summe geringer sein, als die einer Anfrage
ohne den externen Index.</p>
      <p>Es zeigte sich auch, dass, wird eine Integration über
Tabellen angestrebt, es verschiedene Arten gibt, die Ergebnisse
aus der Ergebnistabelle zu entfernen. In 3.1 wurden die
verschiedenen Arten von Tabellen hierfür beschrieben. Wenn
keine Spalte für die AnfrageID verwendet werden muss, so
können die Ergebnisse mit einem TRUNCATE entfernt werden.
Dieses wird erheblich schneller ausgeführt, als ein DELETE
FROM ... WHERE anfrage_id == &lt;current_id&gt;.</p>
      <p>Unsere weitere Arbeit beschränkt sich nicht nur auf eine
Integration in JDBC, die wir hier aufgezeigt haben, sondern
geht auch darüberhinaus auf native Datenbanktreiber ein,
die dann jedoch herstellerspezifisch sind. Hier müssen andere
Mechanismen angewandt werden, eine Integration elegant zu
vollziehen, die Prinzipien bleiben jedoch die gleichen. Auch
der bereits vorgestellte Ansatz, einen Proxy zu integrieren,
der das Protokoll, welches das Datenbanksystem im
Netzwerk verwendet, versteht, wurde weitergeführt und zeigte
sich bereits im Einsatz als wertvolle Hilfe. Das oben bereits
erwähnte Cardigo dient uns dabei als Werkzeugkasten, der
alle diese Möglichkeiten vereint.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>A.</given-names>
            <surname>Adam</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Leuoth</surname>
          </string-name>
          , and
          <string-name>
            <given-names>W.</given-names>
            <surname>Benn</surname>
          </string-name>
          .
          <article-title>Nutzung von Proxys zur Ergänzung von Datenbankfunktionen</article-title>
          . In W.-T. Balke and C. Lofi, editors,
          <source>Grundlagen von Datenbanken</source>
          , volume
          <volume>581</volume>
          <source>of CEUR Workshop Proceedings. CEUR-WS.org</source>
          ,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>E.</given-names>
            <surname>Belden</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Chorma</surname>
          </string-name>
          ,
          <string-name>
            <surname>D. Das</surname>
            ,
            <given-names>Y.</given-names>
          </string-name>
          <string-name>
            <surname>Hu</surname>
            ,
            <given-names>S.</given-names>
          </string-name>
          <string-name>
            <surname>Kotsovolos</surname>
            ,
            <given-names>G.</given-names>
          </string-name>
          <string-name>
            <surname>Lee</surname>
            ,
            <given-names>R.</given-names>
          </string-name>
          <string-name>
            <surname>Leyderman</surname>
            ,
            <given-names>S.</given-names>
          </string-name>
          <string-name>
            <surname>Mavris</surname>
            ,
            <given-names>V.</given-names>
          </string-name>
          <string-name>
            <surname>Moore</surname>
            ,
            <given-names>M.</given-names>
          </string-name>
          <string-name>
            <surname>Morsi</surname>
            ,
            <given-names>C.</given-names>
          </string-name>
          <string-name>
            <surname>Murray</surname>
            ,
            <given-names>D.</given-names>
          </string-name>
          <string-name>
            <surname>Raphaely</surname>
            ,
            <given-names>H.</given-names>
          </string-name>
          <string-name>
            <surname>Slattery</surname>
            ,
            <given-names>S.</given-names>
          </string-name>
          <string-name>
            <surname>Sundara</surname>
          </string-name>
          ,
          <article-title>and</article-title>
          <string-name>
            <given-names>A.</given-names>
            <surname>Yoaz</surname>
          </string-name>
          .
          <source>Oracle Database Data Cartridge Developers Guide, 11g Release</source>
          <volume>2</volume>
          (
          <issue>11</issue>
          .2). Oracle,
          <year>July 2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>P.</given-names>
            <surname>Bruni</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Bortoletto</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Kalyanasundaram</surname>
          </string-name>
          ,
          <string-name>
            <surname>G. McGeoch</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Miller</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Molaro</surname>
          </string-name>
          ,
          <string-name>
            <given-names>Y.</given-names>
            <surname>Ohmori</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Parbs</surname>
          </string-name>
          .
          <article-title>DB2 10 for z/OS Performance Topics</article-title>
          .
          <source>IBM Form Number SG24-7942-00</source>
          ,
          <string-name>
            <given-names>IBM</given-names>
            <surname>Redbooks</surname>
          </string-name>
          ,
          <year>June 2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <surname>Desloch</surname>
          </string-name>
          et al.
          <source>PatNr. US 6</source>
          ,
          <issue>338</issue>
          ,056
          <fpage>B1</fpage>
          -
          <article-title>Relational Database Extender that Supports User-Defined Index Types</article-title>
          and
          <string-name>
            <surname>User-Defined</surname>
            <given-names>Search</given-names>
          </string-name>
          , Apr.
          <year>1999</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>R.</given-names>
            <surname>Elmasri</surname>
          </string-name>
          and
          <string-name>
            <given-names>S. B.</given-names>
            <surname>Navathe</surname>
          </string-name>
          .
          <article-title>Grundlagen von Datenbanksystemen (3</article-title>
          .
          <string-name>
            <surname>Aufl</surname>
          </string-name>
          ., Bachelorausgabe).
          <source>Pearson Studium</source>
          ,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>M.</given-names>
            <surname>Fisher</surname>
          </string-name>
          , J. Ellis, and
          <string-name>
            <given-names>J. C.</given-names>
            <surname>Bruce</surname>
          </string-name>
          .
          <source>JDBC API Tutorial and Reference. Pearson Education</source>
          ,
          <volume>3</volume>
          <fpage>edition</fpage>
          ,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>E.</given-names>
            <surname>Gamma</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Helm</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Johnson</surname>
          </string-name>
          , and
          <string-name>
            <given-names>J. Vlissides. Design</given-names>
            <surname>Patterns</surname>
          </string-name>
          . Addison-Wesley, Boston, MA, January
          <year>1995</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>IBM. SQL</given-names>
            <surname>Reference</surname>
          </string-name>
          , Volume
          <volume>1</volume>
          .
          <string-name>
            <given-names>IBM</given-names>
            <surname>Corporation</surname>
          </string-name>
          ,
          <year>Nov</year>
          .
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>IBM</given-names>
            <surname>Deutschland GmbH. DB2 Spatial Extender und Geodetic Data Management Feature - Benutzer- und Referenzhandbuch</surname>
          </string-name>
          ,
          <year>July 2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>T.</given-names>
            <surname>Lahdenmäki</surname>
          </string-name>
          and
          <string-name>
            <given-names>M.</given-names>
            <surname>Leach</surname>
          </string-name>
          .
          <article-title>Relational database index design and the optimizers: DB2, Oracle, SQL server</article-title>
          , et al. Wiley-Interscience,
          <year>2005</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>T.</given-names>
            <surname>Langner</surname>
          </string-name>
          and
          <string-name>
            <given-names>D.</given-names>
            <surname>Reiberg</surname>
          </string-name>
          .
          <article-title>J2EE und JBoss: Grundlagen und Profiwissen ; verteilte Enterprise-Applikationen auf Basis von J2EE, JBoss &amp; Eclipse</article-title>
          . Hanser,
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>D.</given-names>
            <surname>Lorentz</surname>
          </string-name>
          and
          <string-name>
            <given-names>M. B.</given-names>
            <surname>Roeser</surname>
          </string-name>
          .
          <source>Oracle Database SQL Language Reference, 11g Release</source>
          <volume>2</volume>
          (
          <issue>11</issue>
          .2). Oracle, Oct.
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <given-names>A.</given-names>
            <surname>Martin</surname>
          </string-name>
          and
          <string-name>
            <given-names>J.</given-names>
            <surname>Goke</surname>
          </string-name>
          . P6spy. http://sourceforge. net/projects/p6spy/.
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <given-names>C.</given-names>
            <surname>Murray</surname>
          </string-name>
          .
          <source>Oracle Spatial Developers Guide, 11g Release</source>
          <volume>2</volume>
          (
          <issue>11</issue>
          .2). Oracle, Dec.
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>G.</given-names>
            <surname>Reese</surname>
          </string-name>
          .
          <article-title>Database Programming with JDBC and Java</article-title>
          ,
          <string-name>
            <given-names>Second</given-names>
            <surname>Edition. O'Reilly</surname>
          </string-name>
          &amp; Associates, Inc., Sebastopol, CA, USA, 2nd edition,
          <year>2000</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [16]
          <string-name>
            <given-names>B.</given-names>
            <surname>Rich</surname>
          </string-name>
          .
          <source>Oracle Database Reference, 11g Release</source>
          <volume>2</volume>
          (
          <issue>11</issue>
          .2), Sept.
          <year>2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          [17]
          <string-name>
            <given-names>G.</given-names>
            <surname>Saake</surname>
          </string-name>
          , K.-U. Sattler,
          <article-title>and</article-title>
          <string-name>
            <given-names>A.</given-names>
            <surname>Heuer</surname>
          </string-name>
          . Datenbanken:
          <article-title>Konzepte und Sprachen, 3</article-title>
          . Auflage. mitp-Verlag,
          <source>Redline GmbH</source>
          ,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          [18]
          <string-name>
            <given-names>J.</given-names>
            <surname>Shewmaker</surname>
          </string-name>
          . Analyzing dll injection,
          <year>2006</year>
          . GSM Presentation, Bluenotch.
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          [19]
          <string-name>
            <given-names>M.</given-names>
            <surname>Smedberg</surname>
          </string-name>
          . Boilerplate JDBC Wrapper. http:// blog.redfin.com/devblog/2011/03/boilerplate_ jdbc_wrapper.html.
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          [20]
          <string-name>
            <given-names>K.</given-names>
            <surname>Stolze</surname>
          </string-name>
          and
          <string-name>
            <given-names>T.</given-names>
            <surname>Steinbach</surname>
          </string-name>
          .
          <article-title>DB2 Index Extensions by example and in detail, IBM Developer works DB2 library</article-title>
          .
          <source>Dec</source>
          .
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          [21]
          <string-name>
            <surname>Thedwick</surname>
          </string-name>
          , LLC. jdbcgrabber. http://code.google. com/p/jdbcgrabber/.
        </mixed-citation>
      </ref>
      <ref id="ref22">
        <mixed-citation>
          [22]
          <string-name>
            <given-names>C.</given-names>
            <surname>Wege</surname>
          </string-name>
          .
          <article-title>Steps out of Integration Hell - Protocol Interception Wrapper</article-title>
          . In A. Rüping,
          <string-name>
            <given-names>J.</given-names>
            <surname>Eckstein</surname>
          </string-name>
          , and C. Schwanninger, editors,
          <source>EuroPLoP</source>
          , pages
          <fpage>455</fpage>
          -
          <lpage>458</lpage>
          . UVK - Universitaetsverlag
          <string-name>
            <surname>Konstanz</surname>
          </string-name>
          ,
          <year>2001</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>