GraphDB - 具有两个连接的非常慢的sparql查询

时间:2018-06-14 11:18:49

标签: sparql rdf graphdb

我的数据库包含有关文档的信息,每个文档都有一个类别,例如

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX: <http://example.com>

:doc1 :hasCategory :category1 .
:category1 rdfs:label "Law" .

大约有100k这样的陈述。

运行简单查询以获取每个类别的文档计数:

SELECT ?category (count(distinct ?doc) as ?count) WHERE {
    ?doc :hasCategory ?category .
} GROUP BY ?category

需要大约0.1秒才能运行。

但要返回类别标签:

SELECT ?category ?label (count(distinct ?doc) as ?count) WHERE {
            ?doc :hasCategory ?category .
            ?category rdfs:label ?label .
} GROUP BY ?category ?label

此查询运行时间超过7秒。

为什么差异如此之大,是否有更优化的查询可以用来获取标签?

2 个答案:

答案 0 :(得分:1)

我发现我可以使用以下查询以0.2秒获得所需的结果:

SELECT ?category (sample(?lbl) as ?label) ?count WHERE {
    ?category rdfs:label ?lbl .
    {
        SELECT ?category (count(distinct ?doc) as ?count) WHERE {
            ?doc :hasCategory ?category .
        } GROUP BY ?category 
    }
} GROUP BY ?category ?count

但我真的不明白为什么效率更高。

答案 1 :(得分:1)

8.6版之前的GraphDB版本使用朴素的LinkedHashMap实现GROUP BY操作,其中散列键由投影的所有元素组成。为了计算哈希码,引擎将内部标识符转换为RDF值。如果字符串较长,则会从外部集合中读取它们,从而产生额外的磁盘操作和额外的CPU来计算哈希码。

优化查询的唯一方法是切换到GraphDB 8.6(目前它是一个后期发布候选版本),它实现了更优化的聚合算法或减少了GROUP BY投影,就像你在答案中所做的那样。