我昨天开始自学SPARQL,我正在练习对抗dbpedia。我正在尝试检索所有在指定目的地附近的两个俱乐部(即斯旺西和牛津)打过球的足球运动员名单。我有以下查询,但有效但速度很慢:
SELECT ?player ?team ?team2
WHERE
{
:Swansea geo:geometry ?point1_1 .
?team dbpedia-owl:ground ?ground .
?ground geo:geometry ?point1_2 .
FILTER (bif:st_distance( ?point1_1, ?point1_2) < 5)
?player dbpedia2:clubs ?team .
:Oxford geo:geometry ?point2_1 .
?team2 dbpedia-owl:ground ?ground2 .
?ground2 geo:geometry ?point2_2 .
FILTER (bif:st_distance( ?point2_1, ?point2_2) < 5)
?player dbpedia2:clubs ?team2 .
}
我的问题是,在dbpedia的查询页面上运行查询时经常会超时(请参阅http://tinyurl.com/d9pkluq)。有没有办法优化这个查询?如果我输入更多城镇,或指定更大的半径进行搜索,我仍然希望它在dbpedia的查询页面中没有超时的情况下运行。
感谢您提供的任何帮助!
答案 0 :(得分:2)
您的查询是完全有效的查询,在理想的世界中,处理查询的SPARQL查询引擎将以最佳方式运行。但是,许多SPARQL实现还没有那么好的查询优化器,所以你经常需要自己优化查询。通常,您可以通过重新排序部分查询来执行此操作。
一种常见的技术是尝试在查询中对图表模式进行排序,以便尽快减少查询结果的数量。请记住,每个图形模式将针对先前模式的每个匹配运行。您可以将查询视为一系列嵌套循环;你想避免在内循环中做很多操作。
在您的查询示例中,您可以按如下方式重新排序:
SELECT ?player ?team ?team2
WHERE
{
:Swansea geo:geometry ?point1_1 .
?team dbpedia-owl:ground ?ground .
?ground geo:geometry ?point1_2 .
FILTER (bif:st_distance( ?point1_1, ?point1_2) < 5)
?player dbpedia2:clubs ?team .
?player dbpedia2:clubs ?team2 .
FILTER(?team != ?team2)
:Oxford geo:geometry ?point2_1 .
?team2 dbpedia-owl:ground ?ground2 .
?ground2 geo:geometry ?point2_2 .
FILTER (bif:st_distance( ?point2_1, ?point2_2) < 5)
}
因此,不是寻找另一个城镇和可能非常多的城镇,俱乐部和球员组合,而是通过将其限制为只有“有趣”球员所效力的球队来限制你所看到的第二支球队的选择。我还添加了一项检查,以避免它与?team
和?team2
的同一个团队匹配。
我不能确定这是否会使你的情况更好,这在很大程度上取决于你正在运行的确切DBPedia端点。但这是你可以试验的那种优化。