如何避免在循环中选择查询或使其更快?

时间:2018-06-05 23:46:23

标签: python sql postgresql sqlalchemy

我程序的这部分执行得太慢了。有测量:

ELEMENTS (pairs)    ELAPSED TIME, s
12                  0.31
4692                126.24
16770               462.55

我认为,问题是我在循环中进行查询或SQL查询过于复杂。但我不知道如何避免这种情况。

def set_major_minor_support(self, session, pairs):
    query = """
        SELECT count_table.current_support::NUMERIC / receipt_count_table.receipt_count::NUMERIC
        FROM
        (SELECT COUNT(*) AS current_support FROM
          (SELECT cartitem_id, receipt_id FROM cartitem WHERE product_id = {major_id}) AS A
          INNER JOIN
          (SELECT cartitem_id, receipt_id FROM cartitem WHERE product_id = {minor_id}) AS B
           ON A.receipt_id = B.receipt_id
        ) AS count_table,
        (SELECT COUNT(*) AS receipt_count FROM receipt) AS receipt_count_table;
    """

    for pair in pairs:
        major_id = pair.major_id
        minor_id = pair.minor_id

        current_query = query.format(major_id=major_id, minor_id=minor_id)

        result = session.execute(current_query).fetchone()[0]
        pair.support_major_minor = result
        print(pair.major_id, pair.support_major_minor)

    session.commit()

    return pairs

如果重要,'cartitem'有10万行。

1 个答案:

答案 0 :(得分:1)

选择性 如何是product_id列?也就是说,它应该过滤数据以获得50%的行,5%的行,0.5%的行?

如果它很低(小于0.5%),只要你有适当的索引,就没有理由认为这个查询应该很慢。您正在选择几行,查询应该很快。

以下索引可以加快您的查询速度:

create index ix1 on cartitem (product_id, receipt_id, cartitem_id);

在另一种情况下,如果它不是真正的选择性,那么查询将会很慢,因为您将处理许多行。

注意:列cartitem_id在子查询中根本不使用它。你为什么选择它?为了加快查询速度,您可以删除它(从查询和新索引中删除)。