为啥这个 SPARQL 查询超时以及如何优化这个查询?

Posted

技术标签:

【中文标题】为啥这个 SPARQL 查询超时以及如何优化这个查询?【英文标题】:Why this SPARQL query times out and how to optimize this query?为什么这个 SPARQL 查询超时以及如何优化这个查询? 【发布时间】:2020-07-29 13:03:24 【问题描述】:

我有这个通过 Wikidata 端点运行的 SPARQL 查询

SELECT ?bLabel ?b ?hLabel ?a ?cLabel
  WHERE
  
    wd:Q11462 ?a ?b.
    wd:Q11095 ?a ?b.
    ?c ?a ?b.
    ?h wikibase:directClaim ?a .
    SERVICE wikibase:label  bd:serviceParam wikibase:language "en" 
  

基本上,我正在寻找由 wd:Q11462 和 wd:Q11095 共享的关系,并查看还有什么共享该关系。它达到了 60 秒的时间限制。

但是,如果我分两部分运行多个查询:

首先,获取共享关系

SELECT ?bLabel ?b ?hLabel ?a
  WHERE
  
    wd:Q11462 ?a ?b.
    wd:Q11095 ?a ?b.
    ?h wikibase:directClaim ?a .
    SERVICE wikibase:label  bd:serviceParam wikibase:language "en" 
  

然后,对于每个获得的关系,运行一个查询以查找与他们共享的其他内容。

"""
SELECT ?cLabel 
  WHERE
  
    ?c wdt:P131 wd:Q3586.
    SERVICE wikibase:label  bd:serviceParam wikibase:language "en" 
  
  """

整个查询只运行 2.5 秒。

由于限制,我希望只用一个查询就能达到同样的速度。我该怎么办?

【问题讨论】:

【参考方案1】:

这是一种使用子查询的方法。需要六秒钟:

 SELECT ?cLabel 
  WITH 
    SELECT ?bLabel ?b ?hLabel ?a
    WHERE 
      wd:Q11462 ?a ?b.
      wd:Q11095 ?a ?b.
      ?h wikibase:directClaim ?a .
     
   as %results
  WHERE 
    INCLUDE %results.
    ?c wdt:P131 wd:Q3586.
    SERVICE wikibase:label  bd:serviceParam wikibase:language "en" 
  

考虑到您观察到的明显差异以及它们在概念上与您连续运行多个查询的方法的接近程度,子查询是自然的扩展。一个更通用的技巧通常会有所帮助,即用手动查询标签来替换标签服务。

在切换到一些具有较少(常用)语句的项目后,我说服了查询服务explain itself。我不能完全声称理解该输出,但据我所知是标签服务将其丢弃(底部表格中的第 5 行):

9             com.bigdata.bop.BOp.bopId 
CONTROLLER    com.bigdata.bop.BOp.evaluationContext
false         com.bigdata.bop.PipelineOp.pipelined
true          com.bigdata.bop.PipelineOp.sharedState
ServiceNode   com.bigdata.bop.controller.ServiceCallJoin.serviceNode
wdq           com.bigdata.bop.controller.ServiceCallJoin.namespace
1596209250127 com.bigdata.bop.controller.ServiceCallJoin.timestamp
[b, h, c]     com.bigdata.bop.join.HashJoinAnnotations.joinVars
null          com.bigdata.bop.join.JoinAnnotations.constraints

此时似乎它试图为 20000 多个项目填充标签。除了将其排除在第一个查询之外,SPARQL 还提供了添加关于理想操作序列的提示的能力,这可能在这里很有用。

【讨论】:

我认为应该是?c ?a ?b,但您的分析似乎是正确的。当我删除该服务时,它显着提高了速度。谢谢。

以上是关于为啥这个 SPARQL 查询超时以及如何优化这个查询?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 SPARQL 查询缺少这么多结果?

使用 WikiData Sparql 高效查询抽象元素

如何递归扩展 SPARQL 构造查询中的空白节点?

为啥我在结果中得到重复? (DBpedia sparql 查询)

SPARQL 查询返回邻居数

SPARQL使用带有限制的子查询