Профилирующий SQL-запрос - PullRequest
5 голосов
/ 09 мая 2011

Я использую 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}

Время 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

1 Ответ

1 голос
/ 29 июня 2011

Одна из возможных причин медлительности - использует ли sql alchemy готовые выражения? Если да, то причина, по которой вы можете испытывать разницу в производительности, заключается в том, что оптимизатор mysql имеет разную информацию при создании двух планов запросов.

Когда вы запускаете запрос из командной строки, оптимизатор mysql имеет полный запрос со всеми заполненными значениями предложения (как вы показали выше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

Таким образом, оптимизатор должен угадать, какие значения вы могли бы использовать, а затем оптимизировать его. К сожалению, это может сделать неверное предположение, и, следовательно, в худшем случае создать план запроса, который сделает запрос значительно медленнее, чем вы ожидаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...