sql - CROSS JOIN 查询性能问题
问题描述
我对 PostgreSQL 数据库版本 10.4 有以下查询:
SELECT
t.pcf ,
t.pcid,
t.description AS "Description",
SUM(t.buys) AS "Buys"
FROM
(
SELECT
t.pcf,
CASE WHEN t.row_index <= 9 THEN t.pcid ELSE NULL END AS pcid,
CASE WHEN t.row_index <= 9 THEN t.description ELSE 'Others' END AS description,
t.buys
FROM
(
SELECT
t.pcf,
t.pcid,
t.description,
t.buys,
row_number() OVER (PARTITION BY t.pcf ORDER BY t.buys DESC) AS row_index
FROM
(
SELECT
cbr.pcid AS pcid,
CONCAT(cbr.title, ' - ', cbr.description) AS description,
pcf,
COUNT(1) AS buys
FROM table1 cbr
CROSS JOIN UNNEST(
ARRAY [${input_list}]) AS pcf
WHERE
cbr.tid IN (
SELECT
cb.tid
FROM table1 cb
WHERE
cb.pcid = pcf
AND cb.startdate >= DATE(${start_date})
AND cb.startdate <= DATE(${end_date})
)
AND cbr.pcid != (pcf)
AND UPPER(cbr.country) = 'ES'
GROUP BY
1, 2, 3
) t
ORDER BY
1, 4 DESC
) AS t
) AS t
GROUP BY
1, 2, 3
ORDER BY
1, 4 DESC
Table1 是一个表,其中每行是某个事件的记录,包含大约 125 万行。
该查询以简化的方式执行以下操作:首先,它查找列pcid在传递的数组中的条目。然后,它查找共享列tid但具有不同pcid的条目(以便具有具有相同tid和多个不同pcid的条目)。然后,对结果进行分组(按某个值排序的前 9 个条目按原样选择,其余的分组为“其他”)
${variable} 表示一个参数。在这种情况下,传递了两个日期和一个整数数组。在传递的列表少于大约 20 个条目的情况下,查询运行正常,但在某些情况下,此列表可能长达 80 个条目。结合较大的日期范围,查询会耗尽资源并给出 DiskFull 错误(在这种情况下,它是 python 异常,但即使直接使用数据库控制台也会出现错误):
OperationalError('(psycopg2.errors.DiskFull) could not write to file "base/pgsql_tmp/pgsql_tmp17143.11561": No space left on device\n')
表 1 看起来像这样(简化):
国家 | pcid | 描述 | 时间 | 开始日期 |
---|---|---|---|---|
ES | 770 | 文本1 | 21d34983-bc4f-4749-a5e8-72b952acf938 | 2021-04-08 |
ES | 770 | 文本2 | 21d37761-bab7-4058-abad-374b54acef6e | 2021-04-12 |
ES | 771 | 其他文本 | 21d54563-81b1-4eb7-9585-0956e03b7fd3 | 2021-04-12 |
ES | 772 | 另一个文本 | 21d54563-81b1-4eb7-9585-0956e03b7fd3 | 2021-04-12 |
ES | 753 | 啊啊啊 | 21d54563-81b1-4eb7-9585-0956e03b7fd3 | 2021-04-12 |
结果应该是这样的:
个人电脑 | pcid | 描述 | 购买 |
---|---|---|---|
770 | 1368 | 标题 1 - 文本 1 | 100 |
771 | 772 | 标题 2 - 文本 2 | 75 |
770 | 753 | 其他标题 - 其他文本 | 23 |
770 | 772 | yeet - 还有另一个文本 | 4 |
770 | 其他 | bbb - aaaaa | 2 |
如果可能的话,我该如何简化这个查询?我认为问题在于 CROSS JOIN,因为将数千或数十万行与大型数组交叉连接可能会填满所有可用内存。目前,仅增加可用内存不是一种选择。
解决方案
推荐阅读
- asp.net - ASP.net 超链接波浪号 ~ URL 未按预期呈现
- r - 按日期字符串过滤文件列表
- json - 如何将响应 json 与 TypeScript 接口 Angular6 对齐
- php - PHP - 通过 RFC 1738 对自定义 URL 进行编码
- java - vaadin $v-background-color 可以以编程方式更改吗?
- protractor - 无法读取未定义的属性“等于”
- php - WordPress 中的 PDF417 条码
- sql - 如何查询未覆盖的时间
- azure - 是否可以在触发器内执行跨分区查询?
- leaflet - 如何在居中的反应传单地图上设置偏移量?