我有一个相当复杂的SPARQL查询,它在并行线程(400个线程)中执行了数千次。为了便于阅读,这里的查询有些简化(命名空间,属性和变量已经减少),但复杂性保持不变(联合,图形数量等)。该查询针对4个图形运行,其中最大的包含5,561,181个三元组。
PREFIX graphA: <GraphABaseURI:>
ASK
FROM NAMED <GraphBURI>
FROM NAMED <GraphCURI>
FROM NAMED <GraphABaseURI>
FROM NAMED <GraphDBaseURI>
WHERE{
{
GRAPH <GraphABaseURI>{
?variableA a graphA:ClassA .
?variableA graphA:propertyA ?variableB .
?variableB dcterms:title ?variableC .
?variableA graphA:propertyB ?variableD .
?variableL<GraphABaseURI:propertyB> ?variableD .
?variableD <propertyBURI> ?variableE
}
.
GRAPH <GraphBURI>{
?variableF <propertyCURI>/<propertyDURI> ?variableG .
?variableF <propertyEURI> ?variableH
}
.
GRAPH <GraphCURI>{
?variableI <http://www.w3.org/2004/02/skos/core#notation> ?variableJ .
?variableI <http://www.w3.org/2004/02/skos/core#prefLabel> ?variableK .
FILTER (isLiteral(?variableK) && REGEX(?variableK, "literalA", "i"))
}
.
FILTER (isLiteral(?variableJ) && ?variableG = ?variableJ) .
FILTER (?variableE = ?variableH)
}
UNION
{
GRAPH <GraphABaseURI>{
?variableA a graphA:ClassA .
?variableA graphA:propertyA ?variableB .
?variableB dcterms:title ?variableC .
?variableA graphA:propertyB ?variableD .
?variableL<propertyBURI> ?variableE .
?variableL <propertyFURI> ?variableD .
}
.
GRAPH <GraphDBaseURI>{
?variableM <propertyGURI> ?variableN .
?variableM <propertyHURI> ?variableO .
FILTER (isLiteral(?variableO) && REGEX(?variableO, "literalA", "i"))
}
.
FILTER (?variableE = ?variableN) .
}
UNION
{
GRAPH <GraphABaseURI>{
?variableA a graphA:ClassA .
?variableA graphA:propertyA ?variableB .
?variableB dcterms:title ?variableC .
?variableA graphA:propertyB ?variableD .
?variableL<propertyBURI> ?variableE .
?variableL <propertyIURI> ?variableD .
}
.
GRAPH <GraphDBaseURI>{
?variableM <propertyGURI> ?variableN .
?variableM <propertyHURI> ?variableO .
FILTER (isLiteral(?variableO) && REGEX(?variableO, "literalA", "i"))
}
.
FILTER (?variableE = ?variableN) .
}
. FILTER (isLiteral(?variableC) && REGEX(?variableC, "literalB", "i")) .
}
我不希望有人改变上面的查询(当然......)。我只发布查询来演示使用的复杂性和所有SPARQL结构。
我的问题:
STR()
强制转换并使用isLiteral()
函数来提高性能。你还可以提出别的建议吗?请注意,我使用Virtuoso开源版,基于Ubuntu构建,版本:07.20.3214,Build:2015年10月14日。
此致 Pantelis Natsiavas
答案 0 :(得分:4)
首先 - 你的Virtuoso版本已经过时了;强烈建议更新为7.20.3217 as of April 2016(或更高版本)。
在查看简化查询时,优化建议自然受到限制。但是这里有几个想法,没有特别的顺序......
Index Scheme Selection,RDF Index Scheme之后的RDF性能调优文档部分提供了一些可能对您的查询和数据有意义的替代和/或其他索引。正如您所说,您的某些模式将定义图形和对象,以及未定义的主题和谓词,其他一些索引可能也有意义(例如,GOPS
,GOSP
) ,取决于其他一些因素。
根据自原始加载后数据的更改量,使用此SQL命令(可以通过任何SQL接口发出 - iSQL,ODBC,JDBC,可能需要重建自由文本索引)等) -
VT_INC_INDEX_DB_DBA_RDF_OBJ ()
Using the bif:contains
predicate可以带来比regex()
过滤器更好的性能,例如替换 -
FILTER (isLiteral(?variableO) && REGEX(?variableO, "literalA", "i")) .
- with -
?variableO bif:contains "'literalA'" .
FILTER ( isLiteral(?variableO) ) .
Explain()
and profile()
可以帮助您进行查询优化工作。这些输出大部分用于开发分析,因此对您来说可能没什么意义,但是将它提供给other Virtuoso users仍然可以提供有用的建议。
由于多种原因,rdf:type
谓词(通常表示为a
,由于SPARQL / Turtle语义糖)可能是性能杀手。从图形模式中删除这些谓词可能会大大提高性能。如果需要,还有其他方法可以限制解决方案集(例如,通过测试只有您希望的rdf:type
实体所拥有的属性),这些方法不会对性能产生负面影响。
(ObDisclaimer:OpenLink Software生成Virtuoso,雇用我。)