[英]how to efficiently use multiprocessing to speed up huge amount of tiny tasks?
[英]python how to speed up on query huge amount of data?
我的任务是:从两个大表中选择数据并对其进行一些操作。
在测试过程中,我发现查询时间真的很长。
耗时:800 秒,TableA 行数 = 1.8M,TableB 行数 = 3.8M
我需要程序可以在 300 秒内完成。
我做了什么:
created
分隔查询,同时运行多个 python(将其分成 2 部分后速度提高了 20%,即使我将部分编号增加到 3,4,5.... 也没有更显着的变化)E.g.
python main.py --created_start=1635343080000 --created_end=1635343140000 --process_id=0 &
python main.py --created_start=1635343140000 --created_end=1635343200000 --process_id=1 &
...
我的部分代码:
...
cur_a = connection.cursor(name=f'fetch_a_{args.process_id}')
cur_a.execute(
f"""
SELECT * FROM tableA WHERE created BETWEEN {args.created_start} AND {args.created_end}
"""
)
cur_b = connection.cursor(name=f'fetch_b_{args.process_id}')
cur_b.execute(
f"""
SELECT * FROM tableB WHERE created BETWEEN {args.created_start} AND {args.created_end}
"""
)
def query_to_set(cur, table_name, table_set, table_pk):
step_size = 20000
_fetched_size = 0
while True:
rows = cur.fetchmany(size=step_size)
if not rows:
break
_fetched_size += len(rows)
print(f"selecting {table_name} data...{_fetched_size} fetched")
#query form DB is a IO-bound task, use multithreading
x = threading.Thread(
target=query_to_set,
args=(cur_a, "tableA")
)
x.start()
y = threading.Thread(
target=query_to_set,
args=(cur_b, "tableB"),
)
y.start()
x.join()
y.join()
您是否已经在 postgres 表上创建了索引? 根据您的查询创建正确的索引应该会显着提高性能。 在您的情况下,您可以在表 tableA 和 tableB 中created
的列上created
BTREE
索引。
DROP INDEX IF EXISTS tableA_created;
CREATE INDEX tableA_created
ON tableA
USING btree (created) ;
DROP INDEX IF EXISTS tableB_created;
CREATE INDEX tableB_created
ON tableB
USING btree (created) ;
然后,您可以尝试通过 postgres 中tableA
和tableB
之间的JOIN
查询替换 python 中的游标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.