繁体   English   中英

python如何加快查询海量数据的速度?

[英]python how to speed up on query huge amount of data?

我的任务是:从两个大表中选择数据并对其进行一些操作。

在测试过程中,我发现查询时间真的很长。

耗时:800 秒,TableA 行数 = 1.8M,TableB 行数 = 3.8M

我需要程序可以在 300 秒内完成。

我做了什么:

  1. 使用命名游标(使用更少的内存,但没有时间差异)
  2. 在选择表格部分时使用线程(没有时间差异)
  3. 使用 fetchmany 而不是简单地循环游标(没有时间差异)
  4. 通过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 中tableAtableB之间的JOIN查询替换 python 中的游标。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM