2011-05-09 117 views
5

我对MySQL使用sqlalchemy(表达式语言,不是完整的ORM),并且遇到了一些意外的缓慢。特别是,通过sqlalchemy执行select查询花费的时间是从mysql命令行执行相同查询所耗费的时间的十倍。从CPROFILE分析SQL查询

输出:

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

MySQL的时间:0.26秒

的共识似乎是,有一些开销使用SQLAlchemy的,但几乎没有这么多。任何有关可能导致这种行为的建议?

的查询是通常的形式:为缓慢

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

确保在sqlalchemy运行之后,您不直接在MySQL中运行查询,否则结果将存在于查询缓存中。如果内存提供服务,RESET QUERY CACHE会清除所有内容。通过sql炼金术不应该有太大的区别。 – SteveMc 2011-05-09 19:11:36

+0

我在发布问题后想过缓存。我打算清除缓存,但初步结果表明这不是问题。 – AAmeliorant 2011-05-09 20:20:11

+0

网络问题 - 如果您是从本地运行MySQL而不是应用程序的远程运行,那可能会导致延迟,但它必须是大量数据和/或网络速度较慢。分析信息几乎排除了sqlalchemy可能做的任何事情。 – SteveMc 2011-05-10 15:20:25

回答

1

一个可能的原因 - 是否SQL炼金术使用预处理语句?如果是,那么您可能遇到性能差异的原因是因为在创建两个查询计划时,mysql优化器具有不同的信息。

当您从命令行运行查询时,mysql优化器具有填充所有where子句值的完整查询(如上面显示的那样),因此可以显式优化这些值。

当从SQL炼金术运行,MySQL优化可能只看到这个(也许fieldnames.race和fieldnames.sex的参数以及):

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 

因此,优化器必须作出一个猜测是什么你可能会使用的值然后围绕它进行优化。不幸的是,这可能会产生一个错误的猜测,因此在最坏的情况下创建一个查询计划,使查询运行速度远远超出您的预期。