Size: 6782
Comment:
|
← Revision 54 as of 2018-04-27 10:45:38 ⇥
Size: 5872
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 5: | Line 5: |
We tested the performance of two triple stores: Virtuoso and RDF-3X. We compare them to our own triple score on a couple of benchmarks. | We tested the performance of two triple stores: Virtuoso and RDF-3X. We compare them to our own triple store on a couple of benchmarks. |
Line 11: | Line 11: |
1. [[http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VOSDownload|Runterladen]] 2. Anweisungen in README-Datei folgen. |
1. [[http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VOSDownload|Herunterladen]] 2. Anweisungen in der README-Datei folgen. |
Line 14: | Line 14: |
1. [[https://code.google.com/p/rdf3x/downloads/list|Runterladen]] | 1. [[https://code.google.com/p/rdf3x/downloads/list|Herunterladen]] |
Line 16: | Line 16: |
=== Installation von SparqlEngineDraft: === 1. [[https://code.google.com/p/rdf3x/downloads/list|Klonen]] 2. [[https://github.com/Buchhold/SparqlEngineDraft#1-build|Anweisungen]] befolgen. |
|
Line 17: | Line 20: |
Um den Datensatz in die beide Stores laden zu können, musste dieser Satz in einen für RDF-Speicherung gängigen Format umgewandelt werden. Ausgewählt wurde "*.nt"-Format. Der ursprünglicher Satz enthielt Values und Enteties. Values waren schon nt-conform, die Enteties mussten umgewandelt werden. Dafür wurden die Enteties in die eckigen Klammer gesetzt und die unzulässige Zeichen durch die entsprechende Prozent-Kodierungen oder auch von uns defenierten Ersatzzeichen ersetzt. |
Um den Datensatz in die Triple-Stores laden zu können, muss dieser Satz in ein für die RDF-Speicherung gängiges Format umgewandelt werden. Ausgewählt wurde das NT-Format. Der ursprüngliche Datensatz enthält Values und Entities. Values waren schon nt-konform, die Entities mussten umgewandelt werden. Dafür wurden die Entities in eckige Klammern gesetzt und unzulässige Zeichen durch die entsprechenden Prozent-Kodierungen oder durch von uns definierte Ersatzzeichen ersetzt (siehe Ersetzungtabelle unten). |
Line 22: | Line 25: |
|| " |||| # |||| % |||| < |||| > |||| [ |||| \ |||| ] |||| ^ |||| { |||| | |||| } |||| ' |||| space || || %22 |||| %23 |||| %25 |||| %3C |||| %3E |||| %5B |||| %5C |||| %5D |||| %5E |||| %7B |||| %7C |||| %7D |||| %60 |||| _ || |
|| % |||| < |||| > |||| \ |||| ^ |||| ` |||| space || || %25 |||| %3C |||| %3E |||| %5C |||| %5E |||| %60 |||| _ || |
Line 25: | Line 28: |
Z.B.: '' 'Mikel Jackson' --> <%60Mikel_Jackson%60> '' Dafür wurde ein kleiner Research gemacht, dessen Ergebnisse [[https://docs.google.com/document/d/1n3p-lpQdCB-2dCIqqAJUC6s5RG01e_y6Fp1xLRbY5HU/edit?usp=sharing|hier]] zusammengefasst wurden. Schlussendlich wurde entschieden aus den Enteties [[http://www.w3.org/TeamSubmission/turtle/#sec-uris|UriRefs]] zu machen. Dafür wurden die Enteties in die eckigen Klammer gesetzt und die unzulässige Zeichen durch die entsprechende Prozent-Kodierungen ersetzt. Die Ersetzungsregeln entsprechen denen von [[http://wiki.dbpedia.org/URIencoding|DBpedia 3.7]]. Als nächstes musste der konvertierter Datensatz in die beiden RDF-Stores geladen werden. |
Z.B.: '' Michael Jackson --> <Michael_Jackson> '' |
Line 30: | Line 31: |
Datenladen in den Virtuoso wurde mit [[http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VirtBulkRDFLoader|Bulk loading process]] gemacht. Bei diesem Prozess muss der Name des RDF-Graphen als graph_iri eingegeben werden. Unter dieser Namen ist der RDF-Satz bei Virtuoso erreichbar und man benutzt graph_iri als prefix bei jeder Entety, wenn man eine Spqrql-Anfrage an den Store erstellt. | Das Importieren der Daten in den Virtuoso Store wurde mit dem [[http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VirtBulkRDFLoader|Bulk loading process]] durchgeführt. Bei diesem Prozess muss der Name des RDF-Graphen als graph_iri eingegeben werden. Unter diesem Namen ist der RDF-Satz bei Virtuoso erreichbar: Wenn man eine Sparql-Anfrage an den Store erstellt, muss man die graph_iri als prefix für jede Entity benutzen. |
Line 32: | Line 33: |
Z.B.: '' 'Mikel%20Jackson' --> '<http://foo/Mikel%20Jackson>' '' | Z.B.: '' Michael Jackson --> '<http://foo/Michael_Jackson>' '' ''*'' Für bessere Ladeperformance empfiehlt sich die Variablen ''NumberOfBuffers'' und ''MaxDirtyBuffers'' in der virtuoso.ini-Datei auf einen höheren Wert zu setzen (genaueres ist in virtuoso.ini beschrieben). Die Datei liegt unter ''<Installationsordner von virtuoso>/var/lib/virtuoso/db/virtuoso.ini'' |
Line 35: | Line 38: |
Das Datenladen in den Rdf3x-Store erfolgt durch einen Skript ''<Installationsordner von Rdf3x>/bin/rdf3xload <DB-Name> <RDF-Satz-Pfad>''. Das wars! Bei der Nfragestellung muss man keinen zusätzlichen Prefix eingeben. | Das Importieren der Daten in den Rdf3x-Store erfolgt durch ein Skript in ''<Installationsordner von Rdf3x>/bin/rdf3xload <DB-Name> <RDF-Satz-Pfad>''. Bei der Anfragegenerierung ist kein zusätzlicher Präfix erforderlich. |
Line 37: | Line 40: |
Z.B.: '' 'Mikel%20Jackson' --> '<Mikel%20Jackson>' '' | Z.B.: '' Michael Jackson --> '<Michael_Jackson>' '' |
Line 39: | Line 42: |
=== Data Import SparqlEngineDraft: === [[https://github.com/Buchhold/SparqlEngineDraft#2-creating-an-index|Anweisungen]] befolgen. Bei der Anfragegenerierung ist kein zusätzlicher Präfix erforderlich. |
|
Line 40: | Line 45: |
=== Ladezeiten: === || '''RDF-Store'''|||| '''Ladezeit'''|| || Virtuoso |||| 1170 min|| || Rdf3x|||| noch nicht gemessen, aber deutlich weniger als bei Virtuoso|| |
Z.B.: '' Michael Jackson --> '<Michael_Jackson>' '' |
Line 45: | Line 47: |
== Queries == === Testvorgang === Als test-Framework wurde ein Python-Skript verwendet. Dabei wurde folgendes Abschnitt immer 3-Fach für jede Kombination Query<>RDF-Store ausgeführt. |
=== Indexerstellung: === |
Line 49: | Line 49: |
''start = int(round(time.time()*1000))'' | Die Größe des Input-RDF-Sets im NT-Format beträgt 17 GB. |
Line 51: | Line 51: |
''process = subprocess.Popen('''command''', stdout=subprocess.PIPE, shell=True)'' | || '''RDF-Store''' |||| '''Ladezeit''' |||| '''Indexgröße auf der Festplatte''' || '''Indexgröße im Arbeitspeicher (unmittelbar nach dem Serverstart)''' || || Virtuoso |||| 23 min |||| 7.9 GB |||| 5.8 GB || || Rdf3x |||| 76 min |||| 12 GB |||| ? || || !SparqlEngineDraft |||| 26 min |||| 14.2 GB |||| 3.5 GB || |
Line 53: | Line 56: |
''out, err = process.communicate()'' | === Tests === |
Line 55: | Line 58: |
''end = int(round(time.time()*1000)) '' | '''Zeilenformat:''' ''<time> (number of lines in result)'' |
Line 57: | Line 60: |
wo | || '''Query \ RDF Store''' |||| '''rdf3x''' |||| '''SparqlEngineDraft''' |||| '''Virtuoso''' || || '''Query 1''' |||| 0.730ms(1) |||| 36.819ms(1) |||| 2433.000ms(1) || || '''Query 2''' |||| 16.472ms(5162) |||| 4.587ms(5162) |||| 121.000ms(5164) || || '''Query 3''' |||| 98.460ms(1579) |||| 57.766ms(1579) |||| 530.000ms(1579) || || '''Query 4''' |||| 24.536ms(9767) |||| 6.898ms(9767) |||| 38.000ms(9767) || || '''Query 5''' |||| 5.164ms(4) |||| 109.617ms(4) |||| 1229.000ms(4) || || '''Query 6''' |||| 75.784ms(0) |||| 41.713ms(0) |||| 138.000ms(0) || || '''Query 7''' |||| 31.728ms(3697) |||| 17.634ms(3697) |||| 101.000ms(3697) || || '''Query 8''' |||| 9.443ms(164) |||| 19.144ms(164) |||| 163.000ms(164) || || '''Query 9''' |||| 0.513ms(128) |||| 2.586ms(128) |||| 883.000ms(128) || || '''Query 10''' |||| 466.715ms(1528) |||| 208.694ms(1528) |||| 801.000ms(1528) || |
Line 59: | Line 72: |
'' '''command''' = virtuosoISQL_path + "isql 127.0.0.1:1113 dba dba " + queryFile'' für Virtuoso '' '''command''' = rdf3x_path + "rdf3xquery" + dataBase + " " + queryFile'' für rdf3x === Anfragen === Für jede Anfrage wurden zwei Datein erstellt die diese Anfrage enthalten: Eine für rdf3x und eine für Virtuoso. '''Beispiel Anfrage für rdf3x:''' ''SELECT * WHERE {'' ''<The%20Format%20(Musical%20Recording)%20%231> ?b ?c'' ''}'' '''Beispiel Anfrage für Virtuoso:''' ''SPARQL SELECT * WHERE {'' ''<http://foo.org/The%20Format%20(Musical%20Recording)%20%231> ?b ?c'' ''};'' '''Getestete Anfragen:''' |
=== Queries === |
Line 87: | Line 76: |
''SELECT * WHERE {'' '' <The%20Format%20(Musical%20Recording)%20%231> ?b ?c'' ''}'' |
{{{ SELECT ?x WHERE { ?x <is-a> <Book> . ?x <Author> <Anthony_Newman_(Author)> } }}} |
Line 95: | Line 85: |
''SELECT * WHERE {'' '' ?a <Length> ?c . FILTER (?c>100)'' ''}'' |
{{{ SELECT ?x WHERE { ?x <Genre> <Comedy> . ?x <is-a> <Award-Nominated_Work> . ?x <is-a> <Film> . } }}} |
Line 103: | Line 95: |
''SELECT * WHERE {'' '' ?x <Release> <Technodrome,%20Volume%202%20(Consumer%20product)> .'' '' ?x <is-a> <Canonical%20Version> .'' '' ?x <is-a> <Musical%20Recording> .'' ''} LIMIT 1000'' |
{{{ SELECT ?x WHERE { ?x <is-a> <Politician> . ?x <Film_performance> ?y . ?y <Genre> <Comedy> . } }}} |
Line 115: | Line 105: |
''SELECT * WHERE {'' '' ?a <is-a> ?c .'' '' ?c <is-a> ?e .'' ''} LIMIT 1000'' |
{{{ SELECT ?x WHERE { ?x <is-a> <Olympic_athlete> . ?x <is-a> <Deceased_Person> } }}} |
Line 125: | Line 114: |
''SELECT * WHERE {'' '' ?a <is-a> ?c .'' '' ?c <is-a> ?e .'' ''}'' |
{{{ SELECT ?x WHERE { ?x <Release> <Technodrome,_Volume_2_(Consumer_product)> . ?x <is-a> <Canonical_Version> . ?x <is-a> <Musical_Recording> . } }}} |
Line 135: | Line 124: |
''SELECT COUNT(*) WHERE {'' '' ?a <is-a> ?c .'' '' ?c <is-a> ?e .'' ''}'' |
{{{ SELECT ?x ?y WHERE { ?x <is-a> <Person> . ?x <Country_of_nationality> <Germany> . ?x <Author> ?y . ?y <is-a> <Award-Nominated_Work> } }}} |
Line 145: | Line 135: |
''SELECT COUNT(*) WHERE {'' | {{{ SELECT ?x WHERE { ?x <is-a> <Politician> . ?x <Parent> ?y . ?x <Parent> ?z . ?y <is-a> <Politician> . ?z <is-a> <Politician> } }}} |
Line 147: | Line 145: |
'' ?a ?b ?c .'' | '''Query 8''' |
Line 149: | Line 147: |
''}'' === Ergebnisse === |
{{{ SELECT ?x ?y WHERE{ ?x <is-a> <Monarch> . ?x <is-a> <Deceased_Person> . ?x <Cause_of_death> <Assassination> . ?x <Place_of_birth> ?y } }}} |
Line 152: | Line 156: |
'''Zeilenformat:''' ''<average time> (<1. loop time>/<2. loop time>/<3. loop time>) ms <number of lines in result> Lines'' | '''Query 9''' |
Line 154: | Line 158: |
|| |||| '''rdf3x''' |||| '''virtuoso''' || || '''Query 1''' |||| 6 (6/5/6) ms 6 Lines |||| 22 (46/10/10) ms 6 Lines || || '''Query 2''' |||| 73088 (70397/73129/75740) ms 8923358 Lines ||||119289 (117564/119475/120828) ms 8282272 Lines || || '''Query 3''' |||| 16 (18/14/18) ms 4 Lines |||| 35 (49/48/10) ms 4 Lines || || '''Query 4''' |||| 11 (13/10/10) ms 1000 Lines |||| 438 (690/341/285) ms 1000 Lines || || '''Query 5''' |||| 163316 (163316/-/-) ms 39690913 Lines |||| 1276218 (1276218/-/-) ms 39919489 Lines || || '''Query 6''' |||| 168517 (168517/-/-) ms 1 Lines |||| 1469 (1521/1456/1430) ms 1 Lines || || '''Query 7''' |||| too Long |||| 1487 (1565/1420/1477) ms 1 || |
{{{ SELECT ?x WHERE{ ?x <is-a> <Lake> . ?x <Contained_by> <Russia> } }}} |
Line 163: | Line 165: |
=== Evaluation === | '''Query 10''' |
Line 165: | Line 167: |
Bei den meisten Testfällen ist rdf3x dem virtuoso überlegen. Jedoch scheint Virtuoso die Aggregierung-Anfragen effizienter zu bearbeiten, wie man das am Beispiel der Queries 6,7 sieht. An den Anfragen 5,6 kann man vermuten, dass rdf3x erstmal die Anfrage 5 ausführt. Danach zählt er die Ergebniszeilen, um die Anfrage 6 zu berechnen. Virtuoso geht offensichtlich anders vor. Desweiteren kann man an der Anfrage 5 erkennen, dass die Ergebnislisten ungleich sind. Grund dafür sind wahrscheinlich die Lesefehler beim RDF-Satz-Laden Leider konnte die Anfrage 7 nur bei Virtuoso ausgeführt werden. Egebnis ist 243035237. Der ursprüngliche Datensatz enthält aber 243036034 Tripel. Es fehlen also 797 Tripel. Weitere Beobachtung ist, dass die Anzahl der Ergebnisse mal bei Virtuoso und mal bei rdf3x größer ist. Sieh Query 2 und 5. Nach dem weiteren Betrachten hat sich ergeben, dass die Values bei rdf3x nicht erkannt wurden, bzw. als einfache Textliterale erkannt. Das führt zu Ergebnisunterschieden bei der Anfrage 2. |
{{{ SELECT ?x ?y ?z WHERE{ ?x <is-a> <Musical_Recording> . ?x <Recorded_by> ?y . ?y <Award_Won> <Bollywood_Movie_Humanitarian_Award> . ?y <Celebrity_friend> ?z . ?z <Profession> <Prophet> } }}} |
Triple Stores
We tested the performance of two triple stores: Virtuoso and RDF-3X. We compare them to our own triple store on a couple of benchmarks.
Software Installation
Installation von Virtuoso Open-Source Edition:
- Anweisungen in der README-Datei folgen.
Installation von rdf3x:
- Kompilieren
Installation von SparqlEngineDraft:
Anweisungen befolgen.
Data Import
Um den Datensatz in die Triple-Stores laden zu können, muss dieser Satz in ein für die RDF-Speicherung gängiges Format umgewandelt werden. Ausgewählt wurde das NT-Format. Der ursprüngliche Datensatz enthält Values und Entities. Values waren schon nt-konform, die Entities mussten umgewandelt werden. Dafür wurden die Entities in eckige Klammern gesetzt und unzulässige Zeichen durch die entsprechenden Prozent-Kodierungen oder durch von uns definierte Ersatzzeichen ersetzt (siehe Ersetzungtabelle unten).
Ersetzungstabelle:
% |
< |
> |
\ |
^ |
` |
space |
||||||
%25 |
%3C |
%3E |
%5C |
%5E |
%60 |
_ |
Z.B.: Michael Jackson --> <Michael_Jackson>
Data Import Virtuoso:
Das Importieren der Daten in den Virtuoso Store wurde mit dem Bulk loading process durchgeführt. Bei diesem Prozess muss der Name des RDF-Graphen als graph_iri eingegeben werden. Unter diesem Namen ist der RDF-Satz bei Virtuoso erreichbar: Wenn man eine Sparql-Anfrage an den Store erstellt, muss man die graph_iri als prefix für jede Entity benutzen.
Z.B.: Michael Jackson --> '<http://foo/Michael_Jackson>'
* Für bessere Ladeperformance empfiehlt sich die Variablen NumberOfBuffers und MaxDirtyBuffers in der virtuoso.ini-Datei auf einen höheren Wert zu setzen (genaueres ist in virtuoso.ini beschrieben). Die Datei liegt unter <Installationsordner von virtuoso>/var/lib/virtuoso/db/virtuoso.ini
Data Import Rdf3x:
Das Importieren der Daten in den Rdf3x-Store erfolgt durch ein Skript in <Installationsordner von Rdf3x>/bin/rdf3xload <DB-Name> <RDF-Satz-Pfad>. Bei der Anfragegenerierung ist kein zusätzlicher Präfix erforderlich.
Z.B.: Michael Jackson --> '<Michael_Jackson>'
Data Import SparqlEngineDraft:
Anweisungen befolgen. Bei der Anfragegenerierung ist kein zusätzlicher Präfix erforderlich.
Z.B.: Michael Jackson --> '<Michael_Jackson>'
Indexerstellung:
Die Größe des Input-RDF-Sets im NT-Format beträgt 17 GB.
RDF-Store |
Ladezeit |
Indexgröße auf der Festplatte |
Indexgröße im Arbeitspeicher (unmittelbar nach dem Serverstart) |
|||
Virtuoso |
23 min |
7.9 GB |
5.8 GB |
|||
Rdf3x |
76 min |
12 GB |
? |
|||
SparqlEngineDraft |
26 min |
14.2 GB |
3.5 GB |
Tests
Zeilenformat: <time> (number of lines in result)
Query \ RDF Store |
rdf3x |
Virtuoso |
||||
Query 1 |
0.730ms(1) |
36.819ms(1) |
2433.000ms(1) |
|||
Query 2 |
16.472ms(5162) |
4.587ms(5162) |
121.000ms(5164) |
|||
Query 3 |
98.460ms(1579) |
57.766ms(1579) |
530.000ms(1579) |
|||
Query 4 |
24.536ms(9767) |
6.898ms(9767) |
38.000ms(9767) |
|||
Query 5 |
5.164ms(4) |
109.617ms(4) |
1229.000ms(4) |
|||
Query 6 |
75.784ms(0) |
41.713ms(0) |
138.000ms(0) |
|||
Query 7 |
31.728ms(3697) |
17.634ms(3697) |
101.000ms(3697) |
|||
Query 8 |
9.443ms(164) |
19.144ms(164) |
163.000ms(164) |
|||
Query 9 |
0.513ms(128) |
2.586ms(128) |
883.000ms(128) |
|||
Query 10 |
466.715ms(1528) |
208.694ms(1528) |
801.000ms(1528) |
Queries
Query 1
SELECT ?x WHERE { ?x <is-a> <Book> . ?x <Author> <Anthony_Newman_(Author)> }
Query 2
SELECT ?x WHERE { ?x <Genre> <Comedy> . ?x <is-a> <Award-Nominated_Work> . ?x <is-a> <Film> . }
Query 3
SELECT ?x WHERE { ?x <is-a> <Politician> . ?x <Film_performance> ?y . ?y <Genre> <Comedy> . }
Query 4
SELECT ?x WHERE { ?x <is-a> <Olympic_athlete> . ?x <is-a> <Deceased_Person> }
Query 5
SELECT ?x WHERE { ?x <Release> <Technodrome,_Volume_2_(Consumer_product)> . ?x <is-a> <Canonical_Version> . ?x <is-a> <Musical_Recording> . }
Query 6
SELECT ?x ?y WHERE { ?x <is-a> <Person> . ?x <Country_of_nationality> <Germany> . ?x <Author> ?y . ?y <is-a> <Award-Nominated_Work> }
Query 7
SELECT ?x WHERE { ?x <is-a> <Politician> . ?x <Parent> ?y . ?x <Parent> ?z . ?y <is-a> <Politician> . ?z <is-a> <Politician> }
Query 8
SELECT ?x ?y WHERE{ ?x <is-a> <Monarch> . ?x <is-a> <Deceased_Person> . ?x <Cause_of_death> <Assassination> . ?x <Place_of_birth> ?y }
Query 9
SELECT ?x WHERE{ ?x <is-a> <Lake> . ?x <Contained_by> <Russia> }
Query 10
SELECT ?x ?y ?z WHERE{ ?x <is-a> <Musical_Recording> . ?x <Recorded_by> ?y . ?y <Award_Won> <Bollywood_Movie_Humanitarian_Award> . ?y <Celebrity_friend> ?z . ?z <Profession> <Prophet> }