2011-05-09 20 views
5

Estoy usando sqlalchemy (lenguaje de expresión, no completo ORM) con MySQL y experimentando una lentitud inesperada. Particularmente, el tiempo dedicado a realizar una consulta de selección en sqlalchemy es diez veces mayor que el tiempo dedicado a realizar la misma consulta desde la línea de comandos de mysql.Profiling SQL query

salida de cprofile:

ncalls tottime percall cumtime percall filename:lineno(function) 
100 206.703 2.067 206.703 2.067 {method 'query' of '_mysql.connection' objects} 

tiempo MySQL: 0.26 segundos

El consenso parece ser que hay alguna sobrecarga usando sqlalchemy, pero no casi tanto. ¿Alguna sugerencia sobre qué podría causar un comportamiento como este?

Las consultas son por lo general de la forma:

SELECT fieldnames.minage, fieldnames.maxage, fieldnames.race,  
fieldnames.sex, sum(pop.population) AS pop, pop.zip5 
FROM pop 
INNER JOIN fieldnames ON fieldnames.fieldname = pop.fieldname_id 
WHERE fieldnames.race IN ("White alone") 
AND fieldnames.sex IN ("Female") 
AND fieldnames.maxage >=101 
AND fieldnames.minage <=107 
GROUP BY fieldnames.minage, fieldnames.maxage 
+0

Asegúrese de no ejecutar la consulta en MySQL inmediatamente después de que sqlalchemy lo ejecute, o el resultado estará en la memoria caché de consultas. Si la memoria sirve, RESET QUERY CACHE borra todo. No debería haber tanta diferencia a través de la alquimia sql. – SteveMc

+0

Pensé en el almacenamiento en caché justo después de publicar la pregunta. Estoy jugando con borrar el caché, pero los resultados preliminares indican que ese no es el problema. – AAmeliorant

+0

Problemas de red: si ejecuta MySQL desde la línea de comando localmente pero el control remoto de su aplicación, eso podría generar retrasos, pero tendría que ser una gran cantidad de datos y/o una red lenta. La información de perfil prácticamente descarta todo lo que sqlalchemy podría estar haciendo. – SteveMc

Respuesta

1

Una posible razón para la lentitud - ¿El uso de SQL alquimia prepara declaraciones? Si es así, entonces una razón por la que puede experimentar una diferencia en el rendimiento es porque el optimizador de mysql tiene información diferente al crear los dos planes de consulta.

Cuando ejecuta la consulta desde la línea de comandos, el optimizador mysql tiene la consulta completa con todos los valores de la cláusula where rellenados (como mostró anteriormente3), por lo tanto puede optimizar explícitamente estos valores.

Al ejecutar SQL de la alquimia, el optimizador de MySQL sólo se puede ver esto (tal vez fieldnames.race y fieldnames.sex son parametrizar también):

SELECT fieldnames.minage, fieldnames.maxage, fieldnames.race,  
fieldnames.sex, sum(pop.population) AS pop, pop.zip5 
FROM pop 
INNER JOIN fieldnames ON fieldnames.fieldname = pop.fieldname_id 
WHERE fieldnames.race IN ("White alone") 
AND fieldnames.sex IN ("Female") 
AND fieldnames.maxage >= ? 
AND fieldnames.minage <= ? 
GROUP BY fieldnames.minage, fieldnames.maxage 

Así, el optimizador tiene que hacer una conjetura sobre lo valores que puede usar, luego optimice alrededor de eso. Desafortunadamente, es posible que adivine mal y, en el peor de los casos, cree un plan de consulta que haga que la consulta se ejecute de forma significativamente más lenta de lo esperado.