Медленные запросы MySQL в Python, но быстро в другом месте

У меня есть время heckuva, занимающееся медленными запросами MySQL в Python. В одной области моего приложения «load data infile» идет быстро. В другой области выбор запросов очень медленный.

Выполнение одного и того же запроса в PhpMyAdmin AND Navicat (как второй тест) дает ответ ~ 5 раз быстрее, чем в Python.

Несколько заметок …

  • Я переключился на MySQLdb в качестве соединителя, и я также использую SSCursor. Нет увеличения производительности.
  • База данных оптимизирована, индексирована и т. Д. Я переношу это приложение на Python из PHP / Codeigniter, где он работал отлично (я по-глупо думал, что выход из PHP поможет ускорить его)
  • PHP / Codeigniter выполняет запросы выбора быстро. Например, один ключевой аспект приложения занимает ~ 2 секунды в PHP / Codeigniter, но занимает 10 секунд на Python, прежде чем выполняется какой-либо анализ данных.

Моя ссылка на базу данных довольно стандартная …

dbconn=MySQLdb.connect(host="127.0.0.1",user="*",passwd="*",db="*", cursorclass = MySQLdb.cursors.SSCursor) 

Любые идеи / помощь / советы будут очень признательны!

ОБНОВИТЬ

Что касается выбора / обработки результатов, я пробовал это несколькими способами. Исходный запрос довольно стандартный …

 # Run Query cursor.execute(query) 

Я удалил весь код в этом цикле, чтобы убедиться, что это не так, как бутылка, и это не так. Я поставил вместо этого фиктивный код. Весь процесс не ускорялся.

 db_results = "test" # Loop Results for row in cursor: a = 0 (this was the dummy code I put in to test) return db_results 

Сам результат запроса – всего 501 строка (большое количество столбцов) … занял 0.029 секунд за пределами Python. Принимая значительно дольше, чем в Python.

Проект связан с скачками. Запрос выполняется внутри этой функции. Сам запрос длинный, однако он отлично работает за пределами Python. Я прокомментировал код в цикле специально для тестирования … также печать (запрос) в надежде понять это.

 # Get PPs def get_pps(race_ids): # Comma Race List race_list = ','.join(map(str, race_ids)) # PPs Query query = ("SELECT raceindex.race_id, entries.entry_id, entries.prognum, runlines.line_id, runlines.track_code, runlines.race_date, runlines.race_number, runlines.horse_name, runlines.line_date, runlines.line_track, runlines.line_race, runlines.surface, runlines.distance, runlines.starters, runlines.race_grade, runlines.post_position, runlines.c1pos, runlines.c1posn, runlines.c1len, runlines.c2pos, runlines.c2posn, runlines.c2len, runlines.c3pos, runlines.c3posn, runlines.c3len, runlines.c4pos, runlines.c4posn, runlines.c4len, runlines.c5pos, runlines.c5posn, runlines.c5len, runlines.finpos, runlines.finposn, runlines.finlen, runlines.dq, runlines.dh, runlines.dqplace, runlines.beyer, runlines.weight, runlines.comment, runlines.long_comment, runlines.odds, runlines.odds_position, runlines.entries, runlines.track_variant, runlines.speed_rating, runlines.sealed_track, runlines.frac1, runlines.frac2, runlines.frac3, runlines.frac4, runlines.frac5, runlines.frac6, runlines.final_time, charts.raceshape " "FROM hrdb_raceindex raceindex " "INNER JOIN hrdb_runlines runlines ON runlines.race_date = raceindex.race_date AND runlines.track_code = raceindex.track_code AND runlines.race_number = raceindex.race_number " "INNER JOIN hrdb_entries entries ON entries.race_date=runlines.race_date AND entries.track_code=runlines.track_code AND entries.race_number=runlines.race_number AND entries.horse_name=runlines.horse_name " "LEFT JOIN hrdb_charts charts ON runlines.line_date = charts.race_date AND runlines.line_track = charts.track_code AND runlines.line_race = charts.race_number " "WHERE raceindex.race_id IN (" + race_list + ") " "ORDER BY runlines.line_date DESC;") print(query) # Run Query cursor.execute(query) # Query Fields fields = [i[0] for i in cursor.description] # PPs List pps = [] # Loop Results for row in cursor: a = 0 #this_pp = {} #for i, value in enumerate(row): # this_pp[fields[i]] = value #pps.append(this_pp) return pps 

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

У вас всего 501 строки, похоже, у вас более 50 колонок. Сколько данных передается от MySQL до Python?

501 строк х 55 столбцов = 27 555 клеток.

Если каждая ячейка усреднила «только» 1K, которая была бы близка к 27 МБ данных.

Чтобы понять, сколько данных mysql нажимает, вы можете добавить это в свой запрос:

 SHOW SESSION STATUS LIKE "bytes_sent" 

Ваш сервер хорошо обеспечен ресурсами? Хорошо ли настроено распределение памяти?

Я предполагаю, что когда вы используете PHPMyAdmin, вы получаете результаты с разбивкой по страницам. Это замаскирует вопрос о том, что MySQL возвращает больше данных, чем может обрабатывать ваш сервер (я не использую Navicat, не уверен, как это возвращает результаты).

Возможно, процесс Python ограничен объемом памяти, и, столкнувшись с этим большим набором результатов, он должен вывести страницу на диск для обработки набора результатов.

Если вы уменьшите количество столбцов, называемых и / или ограничьте, скажем, LIMIT 10 по вашему запросу, вы получаете улучшенную скорость?

Вы можете видеть, работает ли под управлением Python сервер подкачки на диске при вызове этого запроса? Вы можете видеть, какая память распределена для Python, сколько используется во время процесса и как это распределение и использование сравниваются с теми же значениями в версии PHP?

Можете ли вы выделить больше памяти для вашего ограниченного ресурса?

Можете ли вы уменьшить количество столбцов или строк, вызванных разбиением на страницы или асинхронной загрузкой?

Я знаю, что это поздно, однако я столкнулся с аналогичными проблемами с mysql и python. Мое решение состоит в том, чтобы использовать запросы с использованием другого языка … Я использую R, чтобы делать свои запросы, которые слепо быстро, делают то, что я могу в R, а затем отправляю данные на python, если это необходимо для более общего программирования, хотя R имеет много общих так же как и библиотеки. Просто хотел опубликовать что-то, что может помочь кому-то, у кого есть аналогичная проблема, и я знаю, что эта сторона ставит суть проблемы.