Как ускорить код, содержащий запрос sql? - PullRequest
2 голосов
/ 30 мая 2020

Мой фрейм данных содержит около 650 тысяч уникальных строк. Для каждой строки мне нужно получить значение из базы данных. Я использую a для l oop, но время выполнения катастрофически велико, около 25 часов . Как ускорить выполнение кода? Я предполагаю, что вам нужно распараллелить выполнение с помощью joblib или numba. Но наличие запроса sql внутри тела l oop сбивает с толку.

for x in tqdm_notebook(range(len(table))):
    good = table.iloc[x, 0]
    store = table.iloc[x, 1]
    start = table.iloc[x, 6]

    query = f"""
    SELECT 
            good_id,
            store_id,
            AVG(sale) AS avg_sale,
            SUM(sale) AS sum_sale,
            MAX(sale) AS max_sale,
            MIN(sale) AS min_sale
    FROM my_table
    WHERE good_id = {good}
    AND store_id = {store}
    AND date_id BETWEEN DATEADD(MONTH, -2, '{start}') AND DATEADD(MONTH, -1, '{start}')
    GROUP BY good_id, store_id
    """
    temp = pd.read_sql(query, connection)
    if not temp.empty:
        table.iloc[x, 13] = temp['avg_sale'].values
        table.iloc[x, 14] = temp['sum_sale'].values
        table.iloc[x, 15] = temp['max_sale'].values
        table.iloc[x, 16] = temp['min_sale'].values

1 Ответ

2 голосов
/ 30 мая 2020

Для этого вы можете просто расширить свой запрос и получить все кортежи (store, good, day), получить частичные агрегаты для них и выполнить окончательную фильтрацию и агрегирование в pandas. Обратите внимание, что вы меняете AVG на COUNT(*) и вычисляете AVG в окончательном агрегате.

И удобный способ передать список параметров на SQL Сервер с OPEN JSON. Просто отправьте строковый параметр с массивом JSON скаляров, например

'[123,324,445,23,1322]'

или

'["abd","def","d"]'

Так что-то вроде

SELECT 
        good_id,
        store_id,
        date_id,
        count(*)  AS count_sale.
        SUM(sale) AS sum_sale,
        MAX(sale) AS max_sale,
        MIN(sale) AS min_sale
FROM my_table
WHERE good_id in (select cast(value as int) from openjson(?))
AND store_id in (select cast(value as int) from openjson(?))
AND date_id BETWEEN ? and ?
GROUP BY good_id, store_id, date_id
ORDER BY good_id, store_id, date_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...