gpt4 book ai didi

java - Neo4j:模式索引查找比遗留索引慢?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:50:16 25 4
gpt4 key购买 nike

我目前正在将一些旧的 Neo4j 相关代码迁移到新的 Neo4j 2.0.0 测试版。我认为新的模式索引在很多情况下都是一个很好的特性,所以我想更改我的代码以尽可能使用它们。但在这样做之前,我想,我想确定我不会得到更差的表现。所以我写了一个小测试。令人惊讶的是,在查找方面,模式索引的性能始终比遗留索引差。但在下结论之前,我想与您分享我的测试,以便您告诉我我是否做了违法的事情,或者由于测试用例或类似问题的简单性,结果只是这样。另外,您可以自己尝试并确认/拒绝我的观察。因为就目前而言,我宁愿坚持使用遗留索引,它们在 Java 代码中使用时甚至具有一些更好的属性(您不能创建两个具有相同名称的索引,但只会取回现有索引,其中一个模式index 会抛出异常,在索引搜索/获取结果时你有“.single()”方法,其中使用模式索引我似乎必须使用迭代器......)

在我的代码下面。我只是通过注释掉对一种类型的索引(遗留或模式)的调用进行测试,然后运行整个过程几次。我用 N 的各种值进行了尝试,范围从此处显示的 1000 到 60000,始终具有相同的相对结果,即旧索引执行显着更快的查找。显然,我的用例是很多节点,每个节点都有一个唯一的 ID,我需要尽快查找整个节点范围,而我只有节点的 ID。

我的问题是:遗留索引确实更快吗?如果这对我来说是一个主要问题,或者我做错了什么,或者这是一个已知问题,将在测试期间解决并在发布?谢谢!

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.FileUtils;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.graphdb.schema.Schema;
import org.neo4j.tooling.GlobalGraphOperations;

enum labels implements Label {
term
}

public class Neo4jIndexPerformanceTest {
private static int N = 1000;

public static void main(String[] args) throws IOException {
FileUtils.deleteDirectory(new File("tmp/graph.db"));
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase("tmp/graph.db");
try (Transaction tx = graphDb.beginTx()) {
int i = 0;
for (Node n : GlobalGraphOperations.at(graphDb).getAllNodes())
i++;
System.out.println("Number of nodes: " + i);
}
// createLegacyIndex(graphDb);
// searchLegacyIndex(graphDb);
createSchemaIndex(graphDb);
searchSchemaIndex(graphDb);
graphDb.shutdown();
}

private static void searchSchemaIndex(GraphDatabaseService graphDb) {
try (Transaction tx = graphDb.beginTx()) {
IndexDefinition index = graphDb.schema().getIndexes(labels.term).iterator().next();
graphDb.schema().awaitIndexOnline(index, 10, TimeUnit.SECONDS);
}
long time = System.currentTimeMillis();
try (Transaction tx = graphDb.beginTx()) {
for (int i = 0; i < N; i++) {
ResourceIterator<Node> iterator = graphDb.findNodesByLabelAndProperty(labels.term, "id", "schema:" + i).iterator();
if (iterator.hasNext()) {
Node n = iterator.next();
}
iterator.close();
}
}
time = System.currentTimeMillis() - time;
System.out.println("Searching schema index took: " + time + " ms");
}

private static void searchLegacyIndex(GraphDatabaseService graphDb) {
long time = System.currentTimeMillis();
try (Transaction tx = graphDb.beginTx()) {
Index<Node> index = graphDb.index().forNodes("terms");
for (int i = 0; i < N; i++) {
ResourceIterator<Node> iterator = index.get("id", "legacy:" + i).iterator();
if (iterator.hasNext()) {
Node single = iterator.next();
}
iterator.close();
// if (single == null)
// throw new IllegalStateException();
}
}
time = System.currentTimeMillis() - time;
System.out.println("Searching legacy index took: " + time + " ms");

}

private static void createSchemaIndex(GraphDatabaseService graphDb) {
Schema schema = null;
try (Transaction tx = graphDb.beginTx()) {
schema = graphDb.schema();
boolean e = false;
for (IndexDefinition id : graphDb.schema().getIndexes()) {
e = true;
}
if (!e)
schema.indexFor(labels.term).on("id").create();
tx.success();
}
try (Transaction tx = graphDb.beginTx()) {
long time = System.currentTimeMillis();

for (int i = 0; i < N; i++) {
Node n = graphDb.createNode(labels.term);
n.setProperty("id", "schema:" + i);
}

time = System.currentTimeMillis() - time;
schema.awaitIndexesOnline(10, TimeUnit.SECONDS);
tx.success();
System.out.println("Creating schema index took: " + time + " ms");
}
}

private static void createLegacyIndex(GraphDatabaseService graphDb) {
try (Transaction tx = graphDb.beginTx()) {
Index<Node> index = graphDb.index().forNodes("terms");

long time = System.currentTimeMillis();

for (int i = 0; i < N; i++) {
Node n = graphDb.createNode(labels.term);
n.setProperty("id", "legacy:" + i);
index.add(n, "id", n.getProperty("id"));
}

time = System.currentTimeMillis() - time;
tx.success();
System.out.println("Creating legacy index took: " + time + " ms");
}
}
}

最佳答案

我试过你的代码,确实模式索引实现不如传统的那么快。但我找到了原因,这是围绕索引实现的一个简单错误,而不是索引本身。我尝试在本地修复这些错误,它们与旧索引和模式索引的性能完全一样。

所以这是一个适当修复的问题,我只能希望它能进入 2.0 版本。

关于java - Neo4j:模式索引查找比遗留索引慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19996670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com