SQLAlchemy:order_by(None)用于joinload子条款查询?

时间:2014-12-30 21:35:13

标签: python postgresql sqlalchemy

我们在Python 2.7.7和Postgres 9.3上使用SQLAlchemy 0.9.8。

我们有一个使用joinedloads的查询,可以使用单个查询完全填充一些Recipe对象。该查询创建一个大型SQL语句,执行时间为20秒 - 太长。这是rendered SQL statement on Pastebin

呈现的SQL有一个ORDER BY子句,Postgres解释说这是在这个查询上花费99%的时间的来源。这似乎来自ORM模型中的关系,它具有order_by子句。

但是,我们并不关心为此查询返回结果的顺序 - 我们只关心查看单个对象时的顺序。如果我在呈现的SQL语句的末尾删除ORDER BY子句,则查询在不到一秒的时间内执行 - 完美。

我们尝试在查询中使用.order_by(None),但这似乎没有效果。 ORDER BY似乎与joinedloads有关,因为如果将joinedloads更改为lazyloads,它们就会消失。但我们需要加速加速。

如何让SQLAlchemy省略ORDER BY子句?


仅供参考,这是查询:

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')

我们的query()方法看起来像这样(省略了一些joinloads):

@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),
    )

1 个答案:

答案 0 :(得分:6)

[从我在邮件列表上的答案中复制]

你需要从关系()获取order_by,如果排序不重要,可能是最好的想法,或者跳过joinedload(),自己写出连接并使用contains_eager()(http://docs.sqlalchemy.org/en/rel_0_9/orm/loading_relationships.html?highlight=contains_eager#contains-eager )。

joinedload()是一种宏,用于创建对查询的连接和其他修改(例如ORDER BY关系),对每个部分应用别名,以便它们不会与查询中的任何内容冲突,然后将列从这些额外的FROM子句路由到集合和相关对象。 contains_eager()只是最后一部分。在这种情况下,前两个部分,编写连接和排序以及可能使它们混叠(或不混淆)取决于您,因此您可以完全控制查询的呈现方式。