首页 文章

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

提问于
浏览
1

我的数据库包含有关文档的信息,其中每个文档都有一个类别 e.g.

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.1s 才能运行。

但要返回类别标签:

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

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

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

2 回答

  • 1

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

    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

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

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

相关问题