我需要在DBpedia上找到所有三元组,其中http://dbpedia.org/resource/Benin是主题或对象。这个查询以我最适合的格式给出了我想要的输出(只有三个变量,没有空格):
PREFIX : <http://dbpedia.org/resource/>
SELECT * WHERE {
?s ?p ?o
FILTER (?s=:Benin OR ?o=:Benin)
}
如果我有这个查询,我会得到类似的结果:
PREFIX : <http://dbpedia.org/resource/>
SELECT * WHERE {
{:Benin ?p ?o}
UNION
{?s ?p :Benin}
}
然而,后者的格式是关闭的。它首先给我p
和o
输出,将s
留空,然后s
和p
留空o
。此外,第一个查询需要更多时间来执行。我将很感激地解释两个查询如何工作的机制以及为什么输出存在差异。
答案 0 :(得分:4)
然而,后者的格式是关闭的
这是因为两个查询都与SELECT *
具有不同的结果集。联盟加入了元组,但由于某些元组缺少部分,因此输出会产生偏差。
您可以通过明确列出并选择变量来解决问题:
PREFIX : <http://dbpedia.org/resource/>
SELECT ?s ?p ?o WHERE {
{
?s ?p ?o
FILTER (?s=:Benin)
}
UNION
{
?s ?p ?o .
FILTER (?o=:Benin)
}
}
请注意,这在dbpedia上比OR
过滤器更快。
当元组匹配两个过滤器表达式(即:Benin ?p :Benin
)时,联合将返回重复项。
SELECT DISTINCT
会以额外的代价解决这个问题,因为看起来问题不存在,我省略了它以提高性能。
此外,第一个查询需要更多时间来执行。
如果没有EXPLAIN()
的结果,很难说,但我的第一个猜测是等号过滤器正在使用索引,而OR
过滤器正在使用完整的表扫描。对于嵌套过滤器,Virtuoso不seem to generate good query plans。
答案 1 :(得分:2)