Titan数据库:在java代码中迭代数千个顶点的性能问题



我使用的是带有Cassandra后端存储的Titan数据库(版本1.0.0)。我的数据库很大(有数百万个顶点和边)。我正在使用弹性搜索进行索引。它做得很好,而且我相对容易快速地接收到数千个(约40000)顶点作为我的查询答案。但我有性能问题,然后我尝试迭代上千个顶点,并检索保存在顶点属性上的基本数据。我花了大约1分钟!!!

使用Java 8的并行流可以显著提高性能,但还不够(10秒而不是1分钟)。

考虑到我有一千个具有位置属性和时间戳的顶点。我想只检索查询区域中具有位置(Geoshape)的顶点,并收集不同的时间戳。

这是我使用java 8并行流的java代码的一部分:

TitanTransaction tt = titanWraper.getNewTransaction();
PropertyKey timestampKey = tt.getPropertyKey(TIME_STAMP);
TitanGraphQuery graphQuery = tt.query().has(LOCATION, Geo.WITHIN, cLocation);
Spliterator<TitanVertex> locationsSpl = graphQuery.vertices().spliterator();
Set<String> locationTimestamps = StreamSupport.stream(locationsSpl, true)
        .map(locVertex -> {//map location vertices to timestamp String
            String timestamp = locVertex.valueOrNull(timestampKey);
            //this iteration takes about 10 sec to iterate over 40000 vertices
            return timestamp;
         })
         .distinct()
         .collect(Collectors.toSet());

使用标准java迭代的相同代码:

TitanTransaction tt = titanWraper.getNewTransaction();
PropertyKey timestampKey = tt.getPropertyKey(TIME_STAMP);
TitanGraphQuery graphQuery = tt.query().has(LOCATION, Geo.WITHIN, cLocation);
Set<String> locationTimestamps = new HashSet<>();
for(TitanVertex locVertex : (Iterable<TitanVertex>) graphQuery.vertices()) {
    String timestamp = locVertex.valueOrNull(timestampKey);
    locationTimestamps.add(timestamp);        
    //this iteration takes about 45 sec to iterate over 40000 vertices            
}

这种性能让我非常失望。如果结果是大约100万个顶点,那就更糟了。我试图弄清楚这个问题的原因是什么。我预计这将花费我少于1秒的时间来迭代一千个顶点。

相同的查询,但使用gremlin遍历而不是图形查询具有更好的性能和更短的代码:

TitanTransaction tt = graph.newTransaction();
Set<String> locationTimestamps = tt.traversal().V().has(LOCATION, P.within(cLocation))
    .dedup(TIME_STAMP)
    .values(TIME_STAMP)
    .toSet();

最新更新