Как избежать запросов на выбор в цикле или сделать это быстрее? - PullRequest
0 голосов
/ 06 июня 2018

Эта часть моей программы выполняется слишком медленно.Есть измерения:

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 100 000 строк.

1 Ответ

0 голосов
/ 06 июня 2018

Как избирательно является столбцом product_id?То есть, должен ли он фильтровать данные, чтобы получить 50% строк, 5% строк, 0,5% строк?

Если оно низкое (менее 0,5%), нет причины, по которой этот запрос долженбудьте медленными, пока у вас есть соответствующие индексы.Вы выбираете несколько строк, и запрос должен быть быстрым.

Следующий индекс может ускорить ваш запрос:

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

В другом случае, если он не является действительно избирательным, тогдазапрос будет медленным, так как вы будете обрабатывать много строк.

Примечание : столбец cartitem_id вообще не используется в подзапросах.Почему вы выбираете это?Чтобы ускорить запрос, возможно, вам следует удалить его (из запроса и из нового индекса).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...