Estoy usando Python 3.6, mi tabla1 contiene una cantidad bastante grande de datos de los cuales solo necesito un 10% en el área (de la tabla "área"). Pensé que crear una vista primero y analizarla en lugar de la tabla completa1 podría mejorar ampliamente el rendimiento, pero en cambio veo que alrededor de la iteración 200 la velocidad cae dramáticamente a algo así como una iteración por segundo (mientras que al principio era continua flujo de números en la pantalla). Aquí está el código:

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()

¿Alguna idea de por qué sucede esto y cómo solucionarlo? Antes de eso, intenté no crear una vista (y así hacer una preselección), y el ciclo se desaceleró después de unos pocos miles de iteraciones (lo que entiendo es bastante normal), pero lejos de ese ritmo. Una solución alternativa sería cargar todos los datos y luego filtrar el resultado y escribirlo en una nueva tabla. Pero no parece una solución adecuada a largo plazo.

Gracias

-1
GuiOm Clair 24 mar. 2017 a las 14:00

2 respuestas

La mejor respuesta

¿Intentaste hacerlo todo de una vez ?:

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))
''')
1
Clodoaldo Neto 24 mar. 2017 a las 11:38

De hecho, parece que el problema proviene de la forma en que existe la vista en PostgreSQL. Crear una vista materializada parece haber resuelto mi problema. Sin embargo, si alguien tiene una explicación, sería bienvenido.

En caso de que pueda ser de alguna ayuda para alguien, aquí está la nueva versión de mi código:

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()
-1
GuiOm Clair 24 mar. 2017 a las 12:37