千万级单表 sql 查询问题

2019-08-28 14:33:12 +08:00
 Breadykid

划重点:单表 3500w

单表查
表 [用户]
字段 [用户名,金额,日期时间]
查每天同一时间用户 A 和用户 B 金额之和的最大值
如果不用

	
SELECT
	max( a.金额 + b.金额 ),
	a.日期时间 
FROM
	( SELECT 金额,日期时间 FROM 用户表 WHERE 用户名 = 'a' ) a
	LEFT JOIN ( SELECT 金额,日期时间 FROM 用户表 WHERE 用户名 = 'b' ) b 
    	ON a.日期时间 = b.日期时间

该怎么写,不能加索引
上面这个 sql 查得特别慢,近 1 分钟了

5700 次点击
所在节点    程序员
48 条回复
vus520
2019-08-28 14:37:51 +08:00
拆 SQL....
php01
2019-08-28 14:40:41 +08:00
select 金额,日期时间 from 用户表 用户名 in ('a','b');
用程序计算。
此后,加表,作为统计表,统计表同日累加金额。
hosaos
2019-08-28 14:40:54 +08:00
代码里做啊 ,同一时间如果不长的话,先定个变量 MaxMoney=0,取 A 的数据(可分页),然后取 B,值大了就覆盖 MaxMoney
php01
2019-08-28 14:43:19 +08:00
@php01 单表 3500w 数据,光取出来就时间话费很长了。所以你先整体全部算一遍,重新做一张统计表,把统计结果写入,以后每次增改,同步这张统计表。
Breadykid
2019-08-28 14:53:05 +08:00
@php01 目前有类似的统计表,但是没有能放这个数值的表,要是建新表的话里面只有这一个字段,但是直接在 3500w 单表里取,怎么取都要很久,光
```SELECT 金额,日期时间 FROM 用户表 WHERE 用户名 = 'a'```
就花 46s
glacer
2019-08-28 14:53:14 +08:00
为什么不能加索引? join 如果是用临时表的话是无法使用索引的
no1xsyzy
2019-08-28 15:10:01 +08:00
`SELECT 金额,日期时间 FROM 用户表 WHERE 用户名 = 'a'` 取出来有多少个?
Breadykid
2019-08-28 15:16:29 +08:00
Immortal
2019-08-28 16:05:18 +08:00
拿到上一次查询结果的 id 号 作为这一次查询的 where 条件:>id
虽然上一次 id 不一定是昨天的最后一条数据 但肯定小于今天的数据
如果在两天内的数据量下执行 max 可能会好点 你可以试试
shyrock
2019-08-28 16:08:31 +08:00
其他需求都普普通通,但是这个‘不能加索引’就很骚了。。。能问下为什么?
npe
2019-08-28 16:23:07 +08:00
where 用户=a,b
group by 时间
max 金额

----

数据量过大建议分表,可以按月进行拆分。
Aresxue
2019-08-28 16:24:24 +08:00
拆呗,不过也不知道你想咋样啊,你是怕单条 sql 超时了还是怕数据库 IO 时间过长压力过大,亦或是要求必须一条 sql
搞定啊,不知道你想干啥这工作也没法开展不是。如果只是怕数据库长时间 IO 压力太大,就拆呗,搞成几条单表查询,在代码里做计算。如果必须要一条 sql 搞定,你还不准在任何列上用索引,那几乎没啥太大优化空间了,语义上的优化对你这种简单 sql 帮助不大。
jziwenchen
2019-08-28 16:25:35 +08:00
```SELECT 金额,日期时间 FROM 用户表 WHERE 用户名 = 'a'```
这条语句花了 46s ?? 4000w 数据并不多啊 怎么会这么慢...
shadow88sky
2019-08-28 16:27:09 +08:00
将表同步到 elasticsearch 中,学一些简单的 es 语法,就搞定了
jziwenchen
2019-08-28 16:33:08 +08:00
这样可以吗?

select max(a.金额 + b.金额) , 日期
from 表 as a
left join 表 as b on b. 日期 = a.日期
where a.用户='a' and a.用户='b'
arrow8899
2019-08-28 16:37:28 +08:00
这样做的目的是啥
1762628386
2019-08-28 16:40:41 +08:00
建议收购公司,夺得话语权,然后加上索引就行了
liuhuansir
2019-08-28 16:44:01 +08:00
SELECT 金额,日期时间 FROM 用户表 WHERE 用户名 = 'a' 这个都花了 46s,那单纯优化 sql 已经不可能了,纯粹是数据量过大,只能拆了
onepunch
2019-08-28 16:44:20 +08:00
如果是阿里云建议了解一下分析型数据 ,最近接触的业务使用了下非常好用。跟生产数据一致,而且查询都是秒级的。
场景跟你很像,生产环境无法追加索引。

https://cn.aliyun.com/product/ads
ylsc633
2019-08-28 17:03:10 +08:00
粗略看了下 你这是不是可以改成

where name in ('a','b') group by time

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

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

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

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

© 2021 V2EX