Sql 优化特定类型的数据库查询

Sql 优化特定类型的数据库查询,sql,postgresql,sqlalchemy,Sql,Postgresql,Sqlalchemy,我有两个对象之间的多对多关系:引用和书籍。引用可以属于多本书,但通常只有一本或两本。另一方面,一本书通常有多处引用。我有一个对引号的SQL查询,我想将其转换为对至少有一个引号的所有书籍的单个查询: 为了将所有书籍的查询从引号更改为相应的引号,我已执行了以下操作: def get_books(session, quotes): quote_id_query = quotes.from_self(Quote.quote_id) book_query = (sessio

我有两个对象之间的多对多关系:引用和书籍。引用可以属于多本书,但通常只有一本或两本。另一方面,一本书通常有多处引用。我有一个对引号的SQL查询,我想将其转换为对至少有一个引号的所有书籍的单个查询:

为了将所有书籍的查询从引号更改为相应的引号,我已执行了以下操作:

def get_books(session, quotes):
        quote_id_query = quotes.from_self(Quote.quote_id)
        book_query = (session.query(Book)
                             .join(Book.quotes)
                             .filter(Book.book_id.in_(quote_id_query))
                             .distinct())
        return book_query
这是可行的,但对于某些quotes查询来说,这是一种减慢速度的方法。如果quotes为空,则相应的book查询很快,但如果相应的quote查询为非空,则可能需要10秒以上的时间(大约是quotes查询所需时间的1000倍,甚至比N+1查询还要慢)。我正在使用Postgres的最新版本。我的第二张表上有索引,我试图解释和分析这个问题的努力已经达到了一个几乎十几个层次的计划。有人能帮我把这些问题简化成正常的问题吗

编辑:以下是当前的模型定义:

class Quote(BaseModel):
    quote_id = Column(Integer, primary_key=True, nullable=False)
    full_text = Column(String, nullable=False, unique=True)
    uses = Column(Integer, nullable=False)
    popularity = Column(Integer, nullable=False)
    books = relationship('Book', secondary='quotebook', back_populates='quotes')

class Book(BaseModel):
    book_id = Column(Integer, primary_key=True, nullable=False)
    author = Column(String, nullable=False, index=True)
    title = Column(String, nullable=False, index=True)
    genre = Column(String, nullable=False, index=True)
    cost = Column(Integer, nullable=False)
    quotes = relationship('Quote', secondary='quotebook', back_populates='books', lazy='joined')

class QuoteBook(BaseModel):
    __tablename__ = 'quotebook'
    id = Column(Integer, primary_key=True)
    book_id = Column(Integer, ForeignKey('book.book_id'), index=True)
    quote_id = Column(Integer, ForeignKey('quote.quote_id'), index=True)

您应该记录、查看并发布生成供审阅的SQL语句(将sqlalchemy.engine logger设置为INFO),但是您的联接(Book.quotes)应该已经执行内部联接条件,因此您的筛选器(Book.Book\u id.in_quote\u id\u查询)是无关的,应该删除


根据表的大小和定义,如果连接是昂贵的,您也可以考虑使用筛选器(Boo.Quees)测试存在子句的性能。(QuoTIDID>0)

你能给出你的模型定义吗?我可以这么做,但我认为没有什么与众不同的。只有一个报价模型、一本书模型和一个报价电子书模型。因为你的
lazy=“joined”
,您实际上是从
书籍
加入到
引用
两次。您也可以直接从
引用id\u查询
进行加入,而不是在中使用
,这也可能会提高性能。感谢您的帮助,我认为替换IN会有很大帮助。纯粹是猜测,消除额外的加入会有更多帮助删除
中的
,因为db无论如何都应该能够将其优化为联接。