我的数据库包含有关文档的信息,每个文档都有一个类别,例如
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秒。
为什么差异如此之大,是否有更优化的查询可以用来获取标签?
答案 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投影,就像你在答案中所做的那样。