如何加快包含 sql 查询的代码?

Posted

技术标签:

【中文标题】如何加快包含 sql 查询的代码?【英文标题】:How can I speed up the code that contains the sql query? 【发布时间】:2020-05-30 12:41:04 【问题描述】:

我的数据框包含大约 650,000 个唯一行。对于每一行,我需要从数据库中获取一个值。我使用 for 循环,但执行时间非常长,大约 25 小时。如何加快代码执行速度?我假设您需要使用 joblib 或 numba 并行化执行。但是循环体中存在的 sql 查询令人困惑。

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

【问题讨论】:

因为您使用的是 Python 格式字符串而不是 read_sql() with a parameterized query,所以每次迭代都会有不同的 SQL 语句并会导致查询编译命中。 my_table 是否有关于 good_id、store_id、date_id 的覆盖索引? 表有列存储,大小约为10亿行。 无论如何我都会放弃在这里进行 650,000 个单独查询的想法。如果你必须这样做,你至少应该在good_id,store_id, date_id INCLUDE (Sale) 上有一个索引。仅仅依靠列存储意味着每次都会读取所有行。 【参考方案1】:

为此,您可以扩大查询范围并获取所有 (store,good,day) 元组,获取这些元组的部分聚合,然后在 pandas 中执行最终过滤和聚合。请注意,您将 AVG 更改为 COUNT(*) 并在最终聚合中计算 AVG。

将参数列表传递给 SQL Server 的一种便捷方法是使用OPENJSON。只需发送一个带有 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

【讨论】:

以上是关于如何加快包含 sql 查询的代码?的主要内容,如果未能解决你的问题,请参考以下文章

如何加快在 2500 万行上还包含 JOIN 的 SQL UPDATE

如何加快这个oracle选择查询?

php+mysql 如何优化千万级数据模糊查询加快

加快Sql查询

如何加快创建大表 AlphaNumeric 代码的 SQL 脚本

如何加快rbind?