使用 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()
我正在使用 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()