我在玩布拉泽图。我插入了一些表示'events‘的三元组,每个'event’包含3个三元组,如下所示:
<%event-iri%> <http://predicates/timestamp> '2020-01-02T03:04:05.000Z'^^xsd:dateTime .
<%event-iri%> <http://predicates/a> %RANDOM_UUID% .
<%event-iri%> <http://predicates/b> %RANDOM_UUID% .时间戳代表连续的时刻,下一个事件比前一个事件晚1分钟。
我做了两组测试:一次有一百万次事件(所以三百万次),一次有三百万次事件(九百万次三倍)。
我运行的查询如下:
select ?event ?a ?v
where {
?event <http://predicates/timestamp> ?timestamp .
filter (?timestamp >= '2020-01-02T03:04:05.000Z'^^xsd:dateTime && ?timestamp < '2020-01-02T03:03:05.000Z'^^xsd:dateTime)
?event ?a ?v .
}我从返回1000个事件(3000个三元组)的查询开始,然后转到只匹配1个事件(并返回3个三元组)的查询,以确保结果数据集大小不会对范围查询性能本身产生太大影响。
我还尝试添加在这里找到的一个提示,https://sourceforge.net/p/bigdata/discussion/676946/thread/2cf9a1e8/?limit=25告诉Blazegraph,它应该通过添加以下内容来使用范围查询优化
hint:Prior hint:rangeSafe "true" .就在filter条款之后。
还有人提到,对于某些类型,范围查询在为其他类型工作时不起作用(对于ints,它们为johpfe工作),因此我还尝试执行另一组测试,其中时间戳表示为it (Unix时间戳):
<%event-iri%> <http://predicates/timestamp> 1606528746 .
<%event-iri%> <http://predicates/a> %RANDOM_UUID% .
<%event-iri%> <http://predicates/b> %RANDOM_UUID% .我尝试的最后一个查询是
select ?event ?a ?v
where {
?event <http://predicates/timestamp> ?timestamp .
filter (?timestamp >= 1606528746 && ?timestamp < 1606528806)
hint:Prior hint:rangeSafe "true" .
?event ?a ?v .
}无论我如何尝试,我都会得到以下结果:对于较小的数据集(100万时间戳/ints),查询需要1秒,有时更长,但不少于1秒;对于更大的数据集(300万时间戳/ints)查询,至少需要3秒。
差值为3x,与数据量的3倍变化有很好的相关性。因此,看起来范围优化不起作用。
我也和MongoDB做了比较。在“时间戳”字段上有一个索引,它总是在30-50 30内执行类似的查询,而不管数据大小如何。
我做错什么了?有什么方法可以让Blazegraph在这里应用优化吗?
PS。我还尝试将提示放在三模式之后,而不是filter语句之后,按照https://github.com/blazegraph/database/wiki/QueryHints的说法,rangeSafe提示如下:
声明对特定三元模式的查询所接触的数据是强类型的,从而允许将范围筛选器向下推到索引上。
所以查询变成
select ?event ?a ?v
where {
?event <http://predicates/timestamp> ?timestamp .
hint:Prior hint:rangeSafe "true" .
filter (?timestamp >= 1606528746 && ?timestamp < 1606528806)
?event ?a ?v .
}但是这个查询什么也找不到,所以这个提示就会破坏它。
发布于 2020-11-25 13:56:59
下面是优化工作的查询。
这一项适用于整数:
select ?event ?a ?v
where {
?event <http://predicates/timestamp> ?timestamp .
hint:Prior hint:rangeSafe "true" .
filter (?timestamp >= "1606528746"^^xsd:int && ?timestamp < "1606528806"^^xsd:int)
?event ?a ?v .
}当时间戳是日期时,这个例子是这样的:
select ?event ?a ?v
where {
?event <http://predicates/timestamp> ?timestamp .
hint:Prior hint:rangeSafe true .
filter (?timestamp >= '2021-11-07T22:08:24.022+04:00'^^xsd:dateTime && ?timestamp < '2021-11-07T22:10:24.022+04:00'^^xsd:dateTime)
?event ?a ?v .
}阻止优化的原因是:
对于整数的情况,
?timestamp >= 1606528746而不是?timestamp >= "1606528746"^^xsd:int。奇怪的是,它打破了optimization.另外,提示是否包含true或"true"并不重要:这两个选项都成功工作。
非常感谢@StanislavKralin给出了一个工作示例,使用该示例可以将我的查询转换为工作形式。
https://stackoverflow.com/questions/65000453
复制相似问题