使用 psycopg2 在 Python 循环中性能下降

Performance drop in Python loop with psycopg2

我正在使用 Python 3.6,我的 table1 包含相当大量的数据,我只需要其中的 10% 包含在区域中(table "area")。我认为首先创建一个视图并解析它而不是完整的 table1 可以大大提高性能,但我发现在第 200 次迭代左右速度急剧下降到每秒一次迭代(而在首先是屏幕上连续不断的数字流)。这是代码:

import psycopg2

conn = psycopg2.connect("dbname=db_name user=postgres")
cur = conn.cursor()
cur.execute("create view temp as select st_setsrid(the_geom::geometry,2154), table1.gid from tout.area, public.table1 where (st_contains(area.geom,st_setsrid(table1.the_geom::geometry,2154)));")
cur.execute("select count(*) from temp")
nbtotal = cur.fetchone()[0]
print(nbtotal)
for i in range(nbtotal):
    print(i+1, " sur ", nbtotal)
    cur.execute ("insert into tout.table2 (geom) select st_setsrid FROM temp order by gid limit 1 offset "+str(i)+ ";")
    conn.commit()
cur.execute("drop view temp;")
conn.commit()

知道为什么会发生这种情况以及如何解决吗?在此之前,我尝试不创建视图(因此进行预选),并且循环在几千次迭代后变慢(我理解这是很正常的),但远不是那个节奏。解决方法是加载所有数据,然后过滤结果并将其写入新的 table。但它看起来不像是一个合适的长期解决方案。

谢谢

你试过一下子搞定吗?:

cur.execute ('''
    insert into tout.table2 (geom)
    select st_setsrid(the_geom::geometry, 2154)
    from
        tout.area
        inner join
        public.table1 on
            st_contains(area.geom, st_setsrid(table1.the_geom::geometry, 2154))
''')

事实上,问题似乎出在 PostgreSQL 中视图的存在方式上。创建物化视图似乎解决了我的问题。如果有人有解释,那将是受欢迎的。

如果它能对任何人有所帮助,这是我的代码的新版本:

import os, psycopg2

conn = psycopg2.connect("dbname=db_name user=postgres")
cur = conn.cursor()
cur.execute("create materialized view temp as select st_setsrid(the_geom::geometry,2154), table1.gid from tout.area, public.table1 where (st_contains(area.geom,st_setsrid(table1.the_geom::geometry,2154))); select count(*) from temp")
nbtotal = cur.fetchone()[0]
print(nbtotal)
for i in range(nbtotal):
    print(i+1, " sur ", nbtotal)
    cur.execute ("insert into tout.table2 (geom) select st_setsrid FROM temp order by gid limit 1 offset "+str(i)+ ";")
cur.execute("drop materialized view temp;")
conn.commit()