[pyar] [django] Consulta en tabla grande con annotate y Sum

Matias Varela matu.varela en gmail.com
Mie Dic 17 13:17:12 ART 2014


El 17/12/14 11:07, Matias Varela escribió:
> El 06/12/14 12:30, Ariel Rossanigo escribió:
>> +1 a lo que dice Juan Carlos, las 3 queries son distintas. Fijate que
>> por ejemplo la 1 y 2 no tienen el limite de la cantidad de clientes.
>>
>> Ademas de que las queries son distintas, la forma de tratar los datos
>> en Python es distinta.
>> La 1 genera una lista de diccionarios, la 2 una lista de objetos y la
>> tercera una lista de tuplas.
>>
>> La 3er opción es la más rápida porque trae solo 3000 clientes y
>> además no tiene el overhead de generar objetos.
>>
>> ¿Vos necesitas los clientes aún cuando el saldo es 0? 
>> Si es así tenes que partir de "Cliente" como proponías inicialmente y
>> ver donde radica el problema de performance. Si en la base de datos
>> está todo medianamente bien hecho, el motor solo debiera elegir si le
>> conviene hacer un barrido de la tabla de movimientos o no. Esto lo
>> podes ver  en el plan de ejecucion del motor (copias la query que
>> genera el ORM, vas a psql y la ejecutas anteponiendo EXPLAIN o, si se
>> puede por cuestiones de tiempo, EXPLAIN ANALYZE). Si necesitas una
>> mano con esto ultimo copia el resultado en [0] y pasame el link.
>>
>> Además de esto, si vas a tener 8M de movimientos y la consulta la vas
>> a ejecutar periodicamente, te convendría investigar si tenes bien
>> "tuneada" la db. Igual esto ya es medio OT... 
>>
>> Saludos
>> Ariel
>>
>> [0]: http://explain.depesz.com/ 
> Buenos días!
>
> Sigo con este tema. Definitivamente necesito un QuerySet de esto, ya
> que usamos django-tables2 y django-filter que esperan un QuerySet.
> Entonces, la consulta la hago así:
>
>     queryset = Cliente.objects.annotate(saldo=Sum('movimientos__monto'))
>
> En la db:
>
> SELECT
> "core_cliente"."id", "core_cliente"."creado_el",
> "core_cliente"."modificado_el",
> "core_cliente"."nombre", "core_cliente"."apellido",
> "core_cliente"."fecha_nacimiento",
> "core_cliente"."genero", "core_cliente"."estado_civil",
> "core_cliente"."dni",
> "core_cliente"."domicilio", SUM("core_movimientocliente"."monto") AS
> "saldo"
> FROM "core_cliente"
> LEFT OUTER JOIN "core_movimientocliente" ON ( "core_cliente"."id" =
> "core_movimientocliente"."cliente_id" )
> GROUP BY "core_cliente"."id", "core_cliente"."creado_el",
> "core_cliente"."modificado_el", "core_cliente"."nombre",
> "core_cliente"."apellido", "core_cliente"."fecha_nacimiento",
> "core_cliente"."genero", "core_cliente"."estado_civil",
> "core_cliente"."dni", "core_cliente"."domicilio"
>
> Lo que claramente está mal es el group by por todos los campos. En la
> base de datos solo hay 3k clientes con 150K movimientos, y está
> tardando unos 44759 ms aprox.
>
> Ariel, hice el analize explain y lo pegué en [0].
>
> ¿Como le especifico al orm que no haga el group by por todo?
>
> Gracias..
>
> [0] http://explain.depesz.com/s/Eqv
>
> -- 
> *Matías E. Varela*
> Skype: matu.varela
> Jadder: matuu en python.org.ar
>
En este ticket [0] se reportó lo mismo que me está sucediendo. Tiene ya
dos años, pero aún parece no resuelto.

[0] https://code.djangoproject.com/ticket/19259
-- 
*Matías E. Varela*
Skype: matu.varela
Jadder: matuu en python.org.ar

------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20141217/faf4b0f4/attachment.html>


More information about the pyar mailing list