我程序的这部分执行得太慢了。有测量:
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万行。
答案 0 :(得分:1)
选择性 如何是product_id
列?也就是说,它应该过滤数据以获得50%的行,5%的行,0.5%的行?
如果它很低(小于0.5%),只要你有适当的索引,就没有理由认为这个查询应该很慢。您正在选择几行,查询应该很快。
以下索引可以加快您的查询速度:
create index ix1 on cartitem (product_id, receipt_id, cartitem_id);
在另一种情况下,如果它不是真正的选择性,那么查询将会很慢,因为您将处理许多行。
注意:列cartitem_id
在子查询中根本不使用它。你为什么选择它?为了加快查询速度,您可以删除它(从查询和新索引中删除)。