使用 python 阅读优化 cassandra
Read optimisation cassandra using python
我有一个 table 型号如下:
CREATE TABLE IF NOT EXISTS {} (
user_id bigint ,
pseudo text,
importance float,
is_friend_following bigint,
is_friend boolean,
is_following boolean,
PRIMARY KEY ((user_id), is_friend_following)
);
我还有一个 table,里面装着我的种子。这 (20) 个用户是我图表的起点。所以我 select 他们的 ID 并在上面的 table 中搜索以获得他们的关注者和朋友,然后我从那里构建我的图表 (networkX)。
def build_seed_graph(cls, name):
obj = cls()
obj.name = name
query = "SELECT twitter_id FROM {0};"
seeds = obj.session.execute(query.format(obj.seed_data_table))
obj.graph.add_nodes_from(obj.seeds)
for seed in seeds:
query = "SELECT friend_follower_id, is_friend, is_follower FROM {0} WHERE user_id={1}"
statement = SimpleStatement(query.format(obj.network_table, seed), fetch_size=1000)
friend_ids = []
follower_ids = []
for row in obj.session.execute(statement):
if row.friend_follower_id in obj.seeds:
if row.is_friend:
friend_ids.append(row.friend_follower_id)
if row.is_follower:
follower_ids.append(row.friend_follower_id)
if friend_ids:
for friend_id in friend_ids:
obj.graph.add_edge(seed, friend_id)
if follower_ids:
for follower_id in follower_ids:
obj.graph.add_edge(follower_id, seed)
return obj
问题是建图时间太长,想优化一下。
我的 table 'network_table'
中有大约 500 万行。
我想知道如果不使用 where 子句进行查询而只对整个 table 进行单个查询,对我来说是否会更快?它会适合记忆吗?这是一个好主意吗?有更好的方法吗?
您似乎可以去掉最后 2 个 if
语句,因为您正在浏览已经循环过一次的数据:
def build_seed_graph(cls, name):
obj = cls()
obj.name = name
query = "SELECT twitter_id FROM {0};"
seeds = obj.session.execute(query.format(obj.seed_data_table))
obj.graph.add_nodes_from(obj.seeds)
for seed in seeds:
query = "SELECT friend_follower_id, is_friend, is_follower FROM {0} WHERE user_id={1}"
statement = SimpleStatement(query.format(obj.network_table, seed), fetch_size=1000)
for row in obj.session.execute(statement):
if row.friend_follower_id in obj.seeds:
if row.is_friend:
obj.graph.add_edge(seed, row.friend_follower_id)
elif row.is_follower:
obj.graph.add_edge(row.friend_follower_id, seed)
return obj
这也消除了您不使用的列表上的许多追加操作,应该会加快此功能。
我怀疑真正的问题可能不是查询,而是处理时间。
I'm wondering if it would be faster for me if instead of doing a query with a where clauses to just do a single query on whole table? Will it fit in memory? Is that a good Idea? Are there better way?
如果启用分页(https://datastax.github.io/python-driver/query_paging.html - 使用fetch_size),整体上table执行单个查询应该没有任何问题。 Cassandra 会 return 直到 fetch_size 并且会在您从 result_set.
中读取额外的结果。
请注意,如果 table 中有许多与种子无关的行,那么完整扫描可能会较慢,因为您将收到不包含 "seed"[=13 的行=]
免责声明 - 我是构建 ScyllaDB 团队的一员 - 一个兼容 Cassandra 的数据库。
ScyllaDB 最近发布了一篇关于如何有效地并行进行完整扫描的博客 http://www.scylladb.com/2017/02/13/efficient-full-table-scans-with-scylla-1-6/ 这也适用于 Cassandra - 如果完整扫描是相关的并且您可以并行构建图形,那么这可能帮助你。
我有一个 table 型号如下:
CREATE TABLE IF NOT EXISTS {} (
user_id bigint ,
pseudo text,
importance float,
is_friend_following bigint,
is_friend boolean,
is_following boolean,
PRIMARY KEY ((user_id), is_friend_following)
);
我还有一个 table,里面装着我的种子。这 (20) 个用户是我图表的起点。所以我 select 他们的 ID 并在上面的 table 中搜索以获得他们的关注者和朋友,然后我从那里构建我的图表 (networkX)。
def build_seed_graph(cls, name):
obj = cls()
obj.name = name
query = "SELECT twitter_id FROM {0};"
seeds = obj.session.execute(query.format(obj.seed_data_table))
obj.graph.add_nodes_from(obj.seeds)
for seed in seeds:
query = "SELECT friend_follower_id, is_friend, is_follower FROM {0} WHERE user_id={1}"
statement = SimpleStatement(query.format(obj.network_table, seed), fetch_size=1000)
friend_ids = []
follower_ids = []
for row in obj.session.execute(statement):
if row.friend_follower_id in obj.seeds:
if row.is_friend:
friend_ids.append(row.friend_follower_id)
if row.is_follower:
follower_ids.append(row.friend_follower_id)
if friend_ids:
for friend_id in friend_ids:
obj.graph.add_edge(seed, friend_id)
if follower_ids:
for follower_id in follower_ids:
obj.graph.add_edge(follower_id, seed)
return obj
问题是建图时间太长,想优化一下。
我的 table 'network_table'
中有大约 500 万行。
我想知道如果不使用 where 子句进行查询而只对整个 table 进行单个查询,对我来说是否会更快?它会适合记忆吗?这是一个好主意吗?有更好的方法吗?
您似乎可以去掉最后 2 个 if
语句,因为您正在浏览已经循环过一次的数据:
def build_seed_graph(cls, name):
obj = cls()
obj.name = name
query = "SELECT twitter_id FROM {0};"
seeds = obj.session.execute(query.format(obj.seed_data_table))
obj.graph.add_nodes_from(obj.seeds)
for seed in seeds:
query = "SELECT friend_follower_id, is_friend, is_follower FROM {0} WHERE user_id={1}"
statement = SimpleStatement(query.format(obj.network_table, seed), fetch_size=1000)
for row in obj.session.execute(statement):
if row.friend_follower_id in obj.seeds:
if row.is_friend:
obj.graph.add_edge(seed, row.friend_follower_id)
elif row.is_follower:
obj.graph.add_edge(row.friend_follower_id, seed)
return obj
这也消除了您不使用的列表上的许多追加操作,应该会加快此功能。
我怀疑真正的问题可能不是查询,而是处理时间。
I'm wondering if it would be faster for me if instead of doing a query with a where clauses to just do a single query on whole table? Will it fit in memory? Is that a good Idea? Are there better way?
如果启用分页(https://datastax.github.io/python-driver/query_paging.html - 使用fetch_size),整体上table执行单个查询应该没有任何问题。 Cassandra 会 return 直到 fetch_size 并且会在您从 result_set.
中读取额外的结果。请注意,如果 table 中有许多与种子无关的行,那么完整扫描可能会较慢,因为您将收到不包含 "seed"[=13 的行=]
免责声明 - 我是构建 ScyllaDB 团队的一员 - 一个兼容 Cassandra 的数据库。
ScyllaDB 最近发布了一篇关于如何有效地并行进行完整扫描的博客 http://www.scylladb.com/2017/02/13/efficient-full-table-scans-with-scylla-1-6/ 这也适用于 Cassandra - 如果完整扫描是相关的并且您可以并行构建图形,那么这可能帮助你。