我有一个sparql-Query,它询问给定类型的URI的某些属性。由于我不确定,这些属性是否存在,我使用OPTIONAL Keyword:
PREFIX mbo: <http://creativeartefact.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT * WHERE {
?uri a mbo:LiveMusicEvent.
OPTIONAL {?uri rdfs:label ?label}.
OPTIONAL {?uri mbo:organisedBy ?organiser}.
OPTIONAL {?uri mbo:takesPlaceAt ?venue}.
OPTIONAL {?uri mbo:begin ?begin}.
OPTIONAL {?uri mbo:end ?end}.
}
当我针对我的SPARQL-Endpoint(Virtuoso Server)运行此查询时,出现错误:
Virtuoso 42000错误估计执行时间-721420288(秒) 超过400(秒)的限制。
当我减少OPTIONAL子句时,在第一个删除子句之后,估计的执行时间是4106秒,当我删除两个子句时,执行查询(并立即返回值)。
我看不出,为什么估计的执行时间会像其他OPTIONAL条款一样暴涨,但也许我只是使用错误的构造查询?
答案 0 :(得分:7)
对于SPARQL引擎,可选模式通常很昂贵(与#34;普通&#34;连接模式相比)。在这种情况下,错误表明Virtuoso的查询计划程序估计查询太复杂而无法在设定的时间限制内执行(注意它估计这个 - 所以精确值可能是错误的)。
你有几种选择。但是,他们中的大多数都涉及多个查询。一个常见的模式是&#34;检索和迭代&#34;模式 - 您首先执行查询以检索mbo:LiveMusicEvent
的所有实例:
SELECT ?uri WHERE { ?uri a mbo:LiveMusicEvent }
然后迭代结果并检索每个实例的可选属性:
SELECT *
WHERE { VALUES(?uri) { <http://example.org/instance1> }
OPTIONAL {?uri rdfs:label ?label}.
OPTIONAL {?uri mbo:organisedBy ?organiser}.
OPTIONAL {?uri mbo:takesPlaceAt ?venue}.
OPTIONAL {?uri mbo:begin ?begin}.
OPTIONAL {?uri mbo:end ?end}.
}
如您所见,我使用VALUES
clause将第一个查询的实例ID结果插入到第二个查询中。在这个例子中,我假设你逐个迭代,因此对每个实例进行查询,但作为进一步的优化,你可能会修改一次性在VALUES
子句中添加多个实例(显然不是全部)但是,这会使查询与原始查询具有相同的复杂性。
顺便说一下,VALUES
是一个SPARQL 1.1功能,我不确定Virtuoso是否支持它。如果没有,您可以通过使用FILTER
子句或仅通过手动&#39;来实现相同的效果。用每次迭代的实例id替换所有出现的变量?uri
。
处理它的另一种方法是首先执行CONSTRUCT查询,从较大的源检索相关的数据子集,然后使用该子集上的选项执行更复杂的查询。例如:
CONSTRUCT
WHERE {
?uri a mbo:LiveMusicEvent;
?p ?o .
}
将检索有关LiveMusicEvent
个实例的所有数据作为RDF图。将该图表弹出到本地RDF模型(例如,如果您在Java中工作,则为Sesame模型或内存存储库),并从那里进一步查询。