来来来,给这个 sql 来个优化方案

296 天前
 aw2350

SELECT kdojhad, k3jyqb4, ( ( ( SELECT MAX ( calc_65b868adfd5b141878679de2 ) FROM ( SELECT ( SUM ( t623be1f4fd5b1419766ff0b8."c2" ) ) AS calc_65b868adfd5b141878679de2, t623be1f4fd5b1419766ff0b8."c10" AS dimension0 FROM t623be1f4fd5b1419766ff0b8 WHERE ( ( t623be1f4fd5b1419766ff0b8."c11" = k3jyqb4 ) AND ( t623be1f4fd5b1419766ff0b8."c10" = kdojhad ) ) GROUP BY dimension0 ) AS res ) ) ) AS kxxz3vy FROM ( SELECT t623be1f4fd5b1419766ff0b8."c11" AS k3jyqb4, t623be1f4fd5b1419766ff0b8."c10" AS kdojhad FROM t623be1f4fd5b1419766ff0b8 GROUP BY kdojhad, k3jyqb4 ) AS dataSource

2740 次点击
所在节点    数据库
16 条回复
RiESA
296 天前
SELECT kdojhad,
k3jyqb4,
( (
(SELECT MAX ( calc_65b868adfd5b141878679de2 )
FROM
(SELECT ( SUM ( t623be1f4fd5b1419766ff0b8."c2" ) ) AS calc_65b868adfd5b141878679de2,
t623be1f4fd5b1419766ff0b8."c10" AS dimension0
FROM t623be1f4fd5b1419766ff0b8
WHERE ( ( t623be1f4fd5b1419766ff0b8."c11" = k3jyqb4 )
AND ( t623be1f4fd5b1419766ff0b8."c10" = kdojhad ) )
GROUP BY dimension0 ) AS res ) ) ) AS kxxz3vy
FROM
(SELECT t623be1f4fd5b1419766ff0b8."c11" AS k3jyqb4,
t623be1f4fd5b1419766ff0b8."c10" AS kdojhad
FROM t623be1f4fd5b1419766ff0b8
GROUP BY kdojhad, k3jyqb4 ) AS dataSource


帮你优化了一下格式,不用谢
aw2350
296 天前
@RiESA 谢谢 好人一生平安
houfeibin
296 天前
这段 SQL 查询语句可以进行一些优化。首先,可以将内部嵌套的子查询提取为一个临时表,以减少计算的复杂性。其次,可以使用 JOIN 操作来简化查询逻辑。

以下是优化后的 SQL 查询语句:

WITH temp AS (
SELECT t."c10" AS kdojhad, t."c11" AS k3jyqb4, SUM(t."c2") AS calc_65b868adfd5b141878679de2
FROM t623be1f4fd5b1419766ff0b8 t
GROUP BY t."c10", t."c11"
)
SELECT t1.kdojhad, t1.k3jyqb4, t2.max_calc_65b868adfd5b141878679de2 AS kxxz3vy
FROM (
SELECT t."c10" AS kdojhad, t."c11" AS k3jyqb4
FROM t623be1f4fd5b1419766ff0b8 t
GROUP BY t."c10", t."c11"
) t1
JOIN (
SELECT MAX(calc_65b868adfd5b141878679de2) AS max_calc_65b868adfd5b141878679de2
FROM temp
) t2
通过使用临时表和 JOIN 操作,可以将原始查询语句的嵌套子查询和多层括号减少,提高查询效率和可读性。请根据你的实际环境和需求进行测试和调整。
aw2350
296 天前
@houfeibin gpt 的回答明显是有问题的
tradewind
296 天前
第一反应是这样,但是没有造数据不确定有没有问题以及是不是有优化,最好 desc 看看(

```sql
select tmp.kdojhad,
tmp.k3jyqb4,
max(tmp.calc_65b868adfd5b141878679de2) as kxxz3vy
from (select t.kdojhad,
t.k3jyqb4,
sum(t.c2) as calc_65b868adfd5b141878679de2,
t.c10 as dimension0
from t623be1f4fd5b1419766ff0b8 t
where 1
group by t.kdojhad, t.k3jyqb4, dimension0) as tmp
where 1
group by tmp.kdojhad, tmp.k3jyqb4
```

btw 为啥不用代码处理数据
haimianbihdata
296 天前
@houfeibin with as 不是只是提高美观的吗?这个不会提高性能吧?
aw2350
296 天前
@haimianbihdata 会,这个 gpt 的思路是没问题的,就是细节不对。原始的 sql 有关联子查询,影响查询效率。使用 with 生成一个结果集,然后用 join 链接的方式 会提升效率
aw2350
296 天前
@tradewind 这个 sql 并不是手写的,是由业务解析器动态生成的, 所以我要根据场景去优化解析器,而不是具体的 sql
zzNucker
296 天前
@houfeibin 这种代码问题不要贴 GPT 的回答,大概率代码有问题,浪费大家时间
houfeibin
296 天前
@zzNucker 我觉得使用 gpt 就是给自己提供一个解题思路,并不会完全相信 gpt 回答的东西
faithxy
296 天前
SELECT SUM(paid) FROM t WHERE username='aaa';
借楼这个怎么优化 username 是索引,按月分表大概五百万数据,查询频率很高还需要实时数据
thisIsDing
296 天前
简化了一下 SQL ,速度还是要看数据量和索引吧。

diff 信息 https://www.diffchecker.com/gk5R2vD8/

```sql
SELECT
kdojhad,
k3jyqb4,
(((
-- 原来的分组字段已在筛选条件中,所有只有一组,那就不用分组,MAX 也不必取
SELECT
SUM(t623be1f4fd5b1419766ff0b8."c2") AS calc_65b868adfd5b141878679de2
FROM t623be1f4fd5b1419766ff0b8
WHERE (
( t623be1f4fd5b1419766ff0b8."c11" = k3jyqb4 )
AND ( t623be1f4fd5b1419766ff0b8."c10" = kdojhad )
)
))) AS kxxz3vy
FROM (
-- distinct 应该比 group 快
SELECT distinct
t623be1f4fd5b1419766ff0b8."c11" AS k3jyqb4,
t623be1f4fd5b1419766ff0b8."c10" AS kdojhad
FROM t623be1f4fd5b1419766ff0b8
) AS dataSource
```
aw2350
296 天前
@faithxy 按照你的 描述,既然这个表已经 按月分表了,那么肯定有个字段记录的插入时间,假设这个插入时间是个 unix 时间戳 int64 类型
假如 你的 计算只是简单的 SUM(PAID) ,那么完全可以建一个表用来记录当日之前每个人的 SUM 值,然后只需 计算当日新增的 SUM+ 当日之前的 SUM 即可,当日之前的 SUM 值由一个任务半夜生成
如果你用的是一些新型数据库,对于时序数据有很多实时分析插件,可以自己去了解一下
winnievinnie
296 天前
ChatGPT3.5:

你的 SQL 查询包含嵌套查询和聚合函数,要进行优化可能需要根据具体情况进行调整。以下是一些建议的优化方式,但请注意,最终的优化取决于数据库的结构和数据分布。

使用 JOIN 替代子查询:将子查询转换为 JOIN 操作可能提高性能。这取决于具体的数据库系统和索引情况。
sql
Copy code
SELECT
t1.kdojhad,
t1.k3jyqb4,
MAX(t2.calc_65b868adfd5b141878679de2) AS kxxz3vy
FROM
(SELECT t623be1f4fd5b1419766ff0b8."c11" AS k3jyqb4,
t623be1f4fd5b1419766ff0b8."c10" AS kdojhad
FROM t623be1f4fd5b1419766ff0b8
GROUP BY kdojhad, k3jyqb4) AS t1
JOIN
(SELECT
SUM(t623be1f4fd5b1419766ff0b8."c2") AS calc_65b868adfd5b141878679de2,
t623be1f4fd5b1419766ff0b8."c10" AS dimension0
FROM t623be1f4fd5b1419766ff0b8
GROUP BY dimension0) AS t2
ON t1.kdojhad = t2.dimension0 AND t1.k3jyqb4 = k3jyqb4
GROUP BY t1.kdojhad, t1.k3jyqb4;
索引优化:确保涉及到的列上有合适的索引,特别是连接条件的列和 GROUP BY 子句的列。

避免不必要的嵌套:确保嵌套查询的存在是有必要的,如果可以在单一查询中完成,可以尝试简化。

请注意,具体的优化可能需要根据数据库系统的特性和实际数据情况进行调整,建议在实际环境中测试性能。
lookStupiToForce
296 天前
鉴于 po 主连格式化的诚意都没有,我也丢一个没诚意的答案
select a, b, sum(c) as k3jyqb4
from t
group by a, b
自行感悟🙂
dyv9
246 天前
@faithxy 晚上把上个月数据汇总,只有当月查实时,过去的直接拿以前计算好的相加。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1012706

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX