Python зависает на fetchall, используя MySQL коннектор
Я довольно новичок в Python и MySQL. Я пишу код, который запрашивает 60 различных таблиц, каждая из которых содержит записи для каждой секунды в течение пяти минут. Код выполняется каждые пять минут. Некоторые из запросов могут достигать 1/2 МБ данных, но большинство находятся в диапазоне 50 КБ. Я работаю на рабочей станции под управлением Windows 7,64-разрядной версии с использованием MySQL Connector/Python. Я тестирую свой код с помощью Windows PowerShell, но в конечном итоге код будет выполняться как запланированная задача. Рабочая станция имеет много оперативной памяти (8 ГБ). Другие процессы выполняются, но согласно диспетчеру задач используется только половина памяти. В основном все работает как положено, но иногда обработка зависает. Я вставил операторы print в код (я также использовал трассировку отладчика), чтобы определить, где происходит зависание. Это происходит по вызову fetchall. Ниже приведены некоторые части кода. Все CAPS являются (псевдо) константами.
mncdb = mysql.connector.connect(
option_files=ENV_MCG_MYSQL_OPTION_FILE,
option_groups=ENV_MCG_MYSQL_OPTION_GROUP,
host=ut_get_workstation_hostname(),
database=ENV_MNC_DATABASE_NAME
)
for generic_table_id in DBR_TABLE_INDEX:
site_table_id = DBR_SITE_TABLE_NAMES[site_id][generic_table_id]
db_cursor = mncdb.cursor()
db_command = (
"SELECT *"
+" FROM "
+site_table_id
+" WHERE "
+DBR_DATETIME_FIELD
+" >= '"
+query_start_time+"'"
+" AND "
+DBR_DATETIME_FIELD
+" < '"
+query_end_time+"'"
)
try:
db_cursor.execute(db_command)
print "selected data for table "+site_table_id
try:
table_info = db_cursor.fetchall()
print "extracted data for table "+site_table_id
except:
print "DB exception "+formatExceptionInfo()
print "FETCH failed to return any rows..."
table_info = []
raise
except:
print "uncaught DB error "+formatExceptionInfo()
raise
,,, другая обработка, которая использует данные.,, db_cursor.close() mncdb.close() .,, Никаких исключений не выдвигается. В отдельном окне PowerShell я могу получить доступ к данным, обрабатываемым кодом. Для моего тестирования все данные в базе данных загружаются до выполнения кода. Ни один процесс не обновляет базу данных, пока код тестируется. Зависание может произойти при первом выполнении кода или после нескольких часов выполнения.
Мой вопрос заключается в том, что может привести к зависанию кода в операторе fetchall?
2 ответа
Вы можете облегчить это, установив размер выборки:
mncdb = mysql.connector.connect(option_files=ENV_MCG_MYSQL_OPTION_FILE, option_groups=ENV_MCG_MYSQL_OPTION_GROUP,host=ut_get_workstation_hostname(,database=ENV_MNC_DATABASE_NAME, cursorclass = MySQLdb.cursors.SSCursor)
Но прежде чем сделать это, вы должны также использовать оправдание mysql для подготовленных операторов вместо конкатенации строк при построении вашего оператора.
Зависание может включать сами таблицы MySQL, а не код Python. Они содержат много записей? Это очень широкие столы? Они проиндексированы на поле datetime__?
Рассмотрим различные стратегии:
Определенно выберите нужные столбцы вместо звездочки, вызывая все столбцы.
Индекс на
DBR_DATETIME_FIELD
используется в предложении where (т. е. неявное соединение).Дальнейшая диагностика с печатными таймерами
print(datetime.datetime.now())
чтобы увидеть, какие узкие места таблицы. При этом обязательно импортируйтеdatetime
модуль.