Pregunta

Tengo una vista de Django que crea 500-5000 nuevos INSERTOS de base de datos en un bucle. El problema es que es muy lento! Estoy recibiendo alrededor de 100 inserciones por minuto en Postgres 8.3. Solíamos usar MySQL en hardware menor (instancia EC2 más pequeña) y nunca tuvimos este tipo de problemas de velocidad.

Detalles: Postgres 8.3 en Ubuntu Server 9.04. El servidor es un " grande " Amazon EC2 con base de datos en EBS (ext3) - 11GB / 20GB.

Aquí hay algunos de mis postgresql.conf: avíseme si necesita más

shared_buffers = 4000MB
effective_cache_size = 7128MB

Mi python:

for k in kw:
        k = k.lower()
        p = ProfileKeyword(profile=self)
        logging.debug(k)
        p.keyword, created = Keyword.objects.get_or_create(keyword=k, defaults={'keyword':k,})
        if not created and ProfileKeyword.objects.filter(profile=self, keyword=p.keyword).count():
            #checking created is just a small optimization to save some database hits on new keywords
            pass #duplicate entry
        else:
            p.save()

Algunos resultados de la parte superior:

top - 16:56:22 up 21 days, 20:55,  4 users,  load average: 0.99, 1.01, 0.94
Tasks:  68 total,   1 running,  67 sleeping,   0 stopped,   0 zombie
Cpu(s):  5.8%us,  0.2%sy,  0.0%ni, 90.5%id,  0.7%wa,  0.0%hi,  0.0%si,  2.8%st
Mem:  15736360k total, 12527788k used,  3208572k free,   332188k buffers
Swap:        0k total,        0k used,        0k free, 11322048k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                            
14767 postgres  25   0 4164m 117m 114m S   22  0.8   2:52.00 postgres                                                                                                                                            
    1 root      20   0  4024  700  592 S    0  0.0   0:01.09 init                                                                                                                                                
    2 root      RT   0     0    0    0 S    0  0.0   0:11.76 migration/0                                                                                                                                         
    3 root      34  19     0    0    0 S    0  0.0   0:00.00 ksoftirqd/0                                                                                                                                         
    4 root      RT   0     0    0    0 S    0  0.0   0:00.00 watchdog/0                                                                                                                                          
    5 root      10  -5     0    0    0 S    0  0.0   0:00.08 events/0                                                                                                                                            
    6 root      11  -5     0    0    0 S    0  0.0   0:00.00 khelper                                                                                                                                             
    7 root      10  -5     0    0    0 S    0  0.0   0:00.00 kthread                                                                                                                                             
    9 root      10  -5     0    0    0 S    0  0.0   0:00.00 xenwatch                                                                                                                                            
   10 root      10  -5     0    0    0 S    0  0.0   0:00.00 xenbus                                                                                                                                              
   18 root      RT  -5     0    0    0 S    0  0.0   0:11.84 migration/1                                                                                                                                         
   19 root      34  19     0    0    0 S    0  0.0   0:00.01 ksoftirqd/1 

Hazme saber si algún otro detalle sería útil.

¿Fue útil?

Solución

En primer lugar, las operaciones de ORM siempre serán más lentas que SQL puro. Una vez escribí una actualización de una base de datos grande en código ORM y la puse en marcha, pero la dejé después de varias horas cuando había completado solo una pequeña fracción. Después de reescribirlo en SQL, todo se ejecutó en menos de un minuto.

En segundo lugar, tenga en cuenta que su código aquí está realizando hasta cuatro operaciones de base de datos separadas para cada fila en su conjunto de datos: el get en get_or_create, posiblemente también el create , el count en el filtro, y finalmente el save . Eso es un montón de acceso a la base de datos.

Teniendo en cuenta que un máximo de 5000 objetos no es enorme, debería poder leer todo el conjunto de datos en la memoria al comienzo. Luego puede hacer un solo filter para obtener todos los objetos de palabras clave existentes de una sola vez, guardando una gran cantidad de consultas en la palabra clave get_or_create y también evitando la necesidad de crear instancias duplicadas ProfileKeywords en primer lugar.

Otros consejos

Una razón común para las operaciones masivas lentas como esta es que cada inserción ocurre en su propia transacción. Si puede lograr que todos ocurran en una sola transacción, podría ir mucho más rápido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top