Мы используем SQLAlchemy 0.9.8 на Python 2.7.7 и Postgres 9.3.SQLAlchemy: order_by (Нет) для запросов подзаголовки подключений?
У нас есть запрос, который использует joinloads для полного заполнения некоторых объектов Recipe с использованием одного запроса. Запрос создает большой оператор SQL, который занимает 20 секунд для выполнения - слишком долго. Вот rendered SQL statement on Pastebin.
Представленный SQL имеет предложение ORDER BY, которое объясняет Postgres, является источником 99% времени, затраченного на этот запрос. Похоже, что это связано с отношением в модели ORM, которая имеет предложение order_by.
Однако мы не заботимся о том, чтобы результаты были возвращены для этого запроса - мы заботимся о заказе только при взгляде на один объект. Если я удалю предложение ORDER BY в конце обработанного оператора SQL, запрос выполняется менее чем за секунду - отлично.
Мы попытались использовать .order_by (None) в запросе, но это, кажется, не имеет никакого эффекта. ORDER BY, по-видимому, связан с соединенными нагрузками, потому что если вы меняете одноразовые нагрузки на lazyloads, они уходят. Но нам нужны переменные скорости.
Как я могу заставить SQLAlchemy опустить предложения ORDER BY?
FYI, вот запрос:
missing_recipes = cls.query(session).filter(Recipe.id.in_(missing_recipe_ids)) if missing_recipe_ids else []
Вот отрывок из класса ORM:
class Recipe(Base, TransactionalIdMixin, TableCacheMixin, TableCreatedModifiedMixin):
__tablename__ = 'recipes'
authors = relationship('RecipeAuthor', cascade=OrmCommonClass.OwnedChildCascadeOptions,
single_parent=True,
lazy='joined', order_by='RecipeAuthor.order', backref='recipe')
scanned_photos = relationship(ScannedPhoto, backref='recipe', order_by="ScannedPhoto.position")
utensils = relationship(CookingUtensil, secondary=lambda: recipe_cooking_utensils_table)
utensil_labels = association_proxy('utensils', 'name')
Наш запрос() метод выглядит примерно так (еще несколько joinedloads опущены) :
@classmethod
def query(cls, session):
query = query.options(
joinedload(cls.ingredients).joinedload(RecipeIngredient.ingredient),
joinedload(cls.instructions),
joinedload(cls.scanned_photos),
joinedload(cls.tags),
joinedload(cls.authors),
)
Мы пробовали обе вещи - выполнение самих стыков было сложным. Мы закончили удаление предложений order_by и сортировку объектов в python в тех местах, которые нам были нужны, отсортированы. Это привело нас к запросу, который занимает 1,5 секунды, почти достаточно быстро. Чтобы идти быстрее, кажется, что нам, вероятно, придется отобразить ответы, которые нужны нам блоку, чтобы избежать накладных расходов на восстановление объектов SQLAlchemy. –