分析SQL查询

AAm*_*ant 5 python sql sqlalchemy

我正在使用sqlalchemy(表达式语言,而不是完整的ORM)与MySQL并经历一些意想不到的缓慢.特别是,sqlalchemy执行选择查询所花费的时间比从mysql命令行执行相同查询所花费的时间大十倍.

cprofile的输出:

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

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
Run Code Online (Sandbox Code Playgroud)

Gar*_*eth 1

缓慢的一个可能原因 - sql alchemy 是否使用准备好的语句?如果是,那么您可能遇到性能差异的原因是 mysql 优化器在创建两个查询计划时具有不同的信息。

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

当您从 sql alchemy 运行时,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
Run Code Online (Sandbox Code Playgroud)

因此,优化器必须猜测您可能使用的值,然后围绕该值进行优化。不幸的是,它可能会做出错误的猜测,因此在最坏的情况下创建一个查询计划,使查询运行速度明显慢于您的预期。