上周我一直在尝试 Neo4j 和索引。我用 faker 库创建了假数据。创建名为 A 的 10k 节点,其属性为:a1、a2、a3、a4。还创建了 10k 个名为 B 的节点,其属性为:b1、b2、b3。我已经将其设置为 a1、b1 和 b2 为 100 个值,重复超过 10k。我创建了 2 个索引,一个包含所有属性,另一个仅包含少数属性。我想测试速度。
import pandas as pd
import timeit
query_A_index_all = "CREATE INDEX IF NOT EXISTS FOR (a:A) ON (a.a1, a.a2, a.a3, a.a4)"
query_B_index_all = "CREATE INDEX IF NOT EXISTS FOR (b:B) ON (b.b1, b.b2, b.b3)"
query_A_index_partial = "CREATE INDEX IF NOT EXISTS FOR (a:A) ON (a.a1, a.a4)"
query_B_index_partial = "CREATE INDEX IF NOT EXISTS FOR (a:Address) ON (a.address)"
我创建了一个包含某些列(包括索引值)的数据框。
def create_dataframe_with_indexes():
# Fetch data from Neo4j and construct DataFrame
query = """
MATCH (a:A), (b:B)
RETURN a.a1 AS A1,
a.a2 AS A2,
a.a3 AS A3,
a.a4 AS A4,
b.b1 AS B1,
b.b2 AS B2,
b.b3 AS B3,
id(a) AS A_index,
id(b) AS B_index
LIMIT 10000
"""
result = graph.run(query).data()
df = pd.DataFrame(result)
return df
接下来我创建了两个函数,第一个函数用于循环数据框并建立关系。另一个是计算花了多长时间。
def time_relationship_creation(create_relationships_func, df):
execution_time = timeit.timeit(lambda: create_relationships_func(df), number=1)
print(f"Relationship creation took {execution_time} seconds")
# Define function to create relationships
def create_relationships(df):
for _, row in df.iterrows():
A_index = row['A_index']
B_index = row['B_index']
# Create relationship between A and B nodes
query = f"MATCH (a:A), (b:B) WHERE id(a) = {A_index} AND id(b) = {B_index} CREATE (p)-[:HAS_RELATION]->(a)"
graph.run(query)
最后
# For all attributes indexed
graph.run(query_A_index_all)
graph.run(query_B_index_all)
df_all = create_dataframe_with_indexes() # Function to create DataFrame with indexes
time_relationship_creation(create_relationships, df_all)
# For a subset of attributes indexed
graph.run(query_A_index_partial)
graph.run(query_B_index_partial)
df_partial = create_dataframe_with_indexes() # Function to create DataFrame with indexes
time_relationship_creation(create_relationships, df_partial)
使用假数据的主要目的是看看使用更多或更少索引之间的速度是否有任何差异。每个函数的输出与 timeit 函数非常相似。我以为会有更多差异。
Relationship creation took 105.32913679201738 seconds
Relationship creation took 105.4880417920067 seconds
只是想知道这个输出是否有意义?或者也许我在代码中忽略了一些东西?也许这是预期的输出,我只是对此感到困惑。任何想法表示赞赏。谢谢。
创建关系比查找索引节点花费的时间要长得多,因此您的方法只是基本上显示创建关系需要多长时间。索引查找时间被淹没在噪音中。您应该只测试索引查找时间而不任何写入。
您定义
query_B_index_partial
索引的方式似乎也有问题,因为它没有使用正确的标签或属性。