Я выполняю задачи хэширования данных с 11 параллельными процессами, и результаты каждого вычисления регистрируются в таблице InnoDB базы данных MySQL, используя ORM SQLAlchemy. Однако время обработки больше ожидаемого. Если я профилирую выполнение одного из этих параллельных процессов, я вижу, что около 30% времени тратится на метод expire класса InstanceState, который вызывается ... 292 957 736 раз!LOTS вызова метода expire класса InstanceState SQLAlchemy
Вычисление выполняет цикл с 17106 итерациями, а одно завершение выполняется для каждой итерации. В профиле я вижу, что метод фиксации называется 17,868, который, кажется, находится в хорошем порядке (дополнительный код 761, вероятно, принадлежит к другим частям окружающего кода). Однако мне не совсем понятно, что делает этот метод истечения срока действия и почему его следует назвать так много раз. Он называется КАЖДЫЕ строки таблицы при каждой фиксации или что? Это немного похоже на то, что если 17,106^2 == 292,615,236 ... Является ли это нормальным? Существуют ли какие-либо рецепты или советы о том, как лучше делать что-то в этой ситуации? Точный код немного сложнее [это в __computeForEvent(...) method of this file], но, то SQLAlchemy часть концептуально эквивалентно следующему:
for i in range(17106):
propagations = []
for i in range(19):
propagations.append(Propagation(...))
session.add_all(propagations)
session.commit()
где Размножение является базовым подклассу. Любые советы о том, как ускорить работу и избежать этого взрыва истекающих (...) звонков, будут очень оценены.
Я не тестировал все ваши предложения, но я закончил рефакторинг кода, используя только сбросы в основном коде. Я переместил логику фиксации/отката снаружи, на уровне «вызывающего». Это изменение обеспечило лучший контроль над состоянием базы данных (т. Е. Избежать несогласованных состояний в отношении моего конкретного приложения) и устранить проблему с истечением срока действия. –