【问题标题】:GraphDB - very slow sparql query with two connectionsGraphDB - 具有两个连接的非常慢的 sparql 查询
【发布时间】:2018-06-14 11:18:49
【问题描述】:

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

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 秒才能运行。

为什么差异会这么大,有没有更优化的查询可以用来获取标签?

【问题讨论】:

  • 您可以检查和比较两个查询的query plans。你真的需要在每个类别中按标签分组吗?如果每个类别只有一个标签,请尝试SELECT ?category (sample(?label) as ?l) (count(distinct ?doc) as ?count) WHERE { ...} GROUP BY ?category
  • 两个查询的估计迭代次数为 39926。 sample 将耗时减少了一秒,但仍然是 6 秒左右
  • 其实第一个查询是39926,第二个查询是39926.4551683254。
  • 第一条语句 ?doc :hasCategory ?category . 的唯一对象数只有 133 。我原以为它只需要找到 133 个类别的标签

标签: sparql rdf graphdb


【解决方案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

但我真的不明白为什么它更有效。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2016-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 2017-03-18
      • 1970-01-01
      相关资源
      最近更新 更多