4 votos

Aumento de la velocidad de multiprocesamiento de Postgres Python

Estoy tratando de acelerar la velocidad de mi PostGIS consultas utilizando el multiprocesamiento. Mi configuración actual es el uso de python y psycopg2 como a continuación. Aunque esto ha dado un aumento en la velocidad, todavía parece que hay cuellos de botella en la prevención de rápido que la velocidad aumenta y no estoy seguro de dónde ir a continuación.

He aumentado mucho de la postgres parámetros como se sugiere en 'la Optimización del Rendimiento de Postgres', pero cuando ejecuto esto en AWS que nunca parecen estar en cualquier lugar cerca de aprovechar al máximo la memoria RAM o I/O que se debe a las limitaciones de DB actividad aparentemente. Puede alguien sugerir otros métodos para acelerar este proceso?

> import os, sys, psycopg2, multiprocessing, time 
> start = time.time() 
> conn = psycopg2.connect("dbname=template_postgis_20 user=postgres") 
> cur = conn.cursor() 
> cur.execute("""SELECT count(*) FROM sites""") 
> count = cur.fetchall()
> def getOidRanges(rownums, count):
> 
>     oidranges = []
>     for row in rownums:
>         minoid = int(row[0])
>     return oidranges
> 
> def mp(rownums, whereclause):
> 
>     for row in rownums:
>         if row[0] == whereclause:
>             gid1 = int(row[0])
>             cur.execute("""
>             UPDATE sites SET postcode=(SELECT field62 FROM (SELECT field62, COUNT(field62) FROM addressbaseplusbh1_2
>             WHERE ST_Within(addressbaseplusbh1_2.geom, (select geom from sites where gid={0})) GROUP BY field62 ORDER BY count DESC)
>             as postcode LIMIT 1) WHERE gid = {0};""".format(gid1))
>             conn.commit()
> 
>     return
> 
> if __name__ == "__main__":
> 
>     nbrquery = ("""SELECT gid FROM sites ORDER BY gid;""")
>     cur.execute(nbrquery)
>     rownums=cur.fetchall()
> 
>     cores = (multiprocessing.cpu_count()-1)
>     procfeaturelimit = 1
> 
>     oidranges = getOidRanges(rownums, count)
> 
>     if len(oidranges) > 0:
>         pool = multiprocessing.Pool(cores)
> 
>         for oidrange in oidranges:
> 
>             whereclause = oidrange[0]
>             jobs = pool.apply_async(mp, (rownums, whereclause))
> 
>         pool.close()
>         pool.join()
>         jobs.get()
> 
>         try:
>             conn.commit()
>             cur.close()
>             conn.close()
>             end = time.time()
>             print end - start
>         except:
>             pass

EDITAR:

@Craig, tendría que trabajar entonces con esta medida se ejecuta el bloque?

curs.execute("""UPDATE sites SET postcode=(SELECT field62 FROM (SELECT field62, COUNT(field62) FROM addressbaseplusbh1_2 WHERE ST_Within(addressbaseplusbh1_2.geom, 
(select geom from sites where gid={0})) GROUP BY field62 ORDER BY count DESC)
as postcode LIMIT 1) WHERE gid = {0};""".format(whereclause))
return

1voto

McDowell Puntos 62645

Usted puede utilizar dblink en un nativo de Postgres consulta para dividir la consulta en la base de datos de conexiones y ejecutar simultáneamente. Este es, efectivamente, el paralelismo en Postgres en un único servidor. Podría ser imitado en Python, pero yo no lo he probado.

Hay algunas limitaciones: 1) la operación debe ser una instrucción insert, no una actualización. Las inserciones son generalmente más rápido de todos modos como no está la alteración de una tabla existente (depende de su disco duro tal y como yo lo entiendo); 2) usted necesitará un ID entero campo para ser capaz de dividir la consulta en trozos. La adición de una serie de campo es la mejor manera que crea un entero secuencial, que se rompe la obra tan uniformemente como sea posible.

Ver a Mike Gleason paralelo de la función de procesamiento de la información.

Clave de rendimiento sugerencia: utilice el límite de la tabla como la tabla de dividir, no los puntos.

El uso de este método, podemos límite de la etiqueta de ~10 millones de puntos en alrededor de 15.000 polígonos en alrededor de un minuto en un 16 core de Windows Server 2012 con 128Gb de RAM en un SSD. Podría correr más rápido en Linux, pero yo no lo he probado.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X