在之前的一个帖子 https://www.v2ex.com/t/1007852 的讨论引申出的另外一个话题
我说说我的环境:
统计 SQL:
select sum(cost)
from table_name
统计全表的 cost 字段的总和
反正跑了 20s 是没有跑完的。相同的查询在 Clickhouse 跑了 12s ( clickhouse 的配置也不高,而且也是单机环境,非分布式)
想看看各位大神的环境与配置,以及统计的 SQL 大概是什么
如果各位的“轻松”的条件是用索引极大的减少了扫描的数据量,那感觉就不是一个话题了
![]() |
1
djangovcps 2024-01-13 20:49:55 +08:00
我个人使用一般超过 2000 万条,就 g 了,除非表分区或者分表,另外说快的,可能是锁 id 查询快?
|
![]() |
2
RangerWolf OP @djangovcps 差不多,clickhouse 出来之前为了让 MySQL 的统计快一点我都愁死了
|
![]() |
3
djangovcps 2024-01-13 20:55:49 +08:00
纯分析的要不试下 es ,蛮快的,一亿条 sum 应该 1s 内能搞定,如果内存 32G ,0.5s 内可以跑完
|
![]() |
4
j1132888093 2024-01-13 21:05:39 +08:00 ![]() 说快的肯定是指走了索引的情况,绝大多数业务都不会有扫描全表的场景,统计这种业务就不应该在 MySQL 中做
|
![]() |
5
zzNucker 2024-01-13 21:08:47 +08:00 ![]() 一亿条用索引都可能很慢啊。。。。
我也不知道轻松的标准是啥 |
![]() |
6
chendy 2024-01-13 21:11:30 +08:00
隔壁帖子说的是
> 插入为主,简单的查询和统计 总量大,但是每次插的查的都是一小部分 楼主这种上来就全表扫一遍的,除非做缓存要不换啥都慢 顺便一说现在的机器性能真不错,早年这么大的表一个 count(*) 下去都要一会才能查出来 |
![]() |
7
RangerWolf OP @zzNucker 我也不知道,反正我看回复的贴子一堆说“轻轻松松”
|
8
justkfc 2024-01-13 21:14:11 +08:00
轻松主要的途径不就是索引和分区表
|
![]() |
9
awalkingman 2024-01-13 21:15:00 +08:00 ![]() 看了一下原来帖子的发言,大部份说的是简单查询下,我理解的简单查询就是走索引查询数据,没有 join 。mysql count 性能差不是什么冷知识,count ,sum 也算不上简单查询,计算列甚至可能用不上索引。
我理解楼主的情绪,但是发这个帖子的就显得有些没在点上了。 |
10
Leviathann 2024-01-13 21:15:11 +08:00 ![]() 这不是典型的 olap 需求?所谓的轻轻松松都是基于 mysql 作为 oltp 数据库的前提
|
![]() |
11
june4 2024-01-13 21:17:45 +08:00
你都搞全表扫描了,根本不是 mysql 的应用场景,mysql 追求的是尽可能走索引不扫表
|
![]() |
12
zzNucker 2024-01-13 21:22:00 +08:00
@RangerWolf 看了原贴大概是单表 1 亿只按索引简单 select 吧,有需要聚合,计算就不用这个方案了
|
13
iseki 2024-01-13 21:30:48 +08:00 ![]() 你自己都说了 ClickHouse 需要跑 12s 才能完成的全表求和,你觉得大家的“轻轻松松”能是什么标准呢?反正面对一亿行全表统计,我个人视能在分钟内完成就是可以忍受的,到底是不是轻轻松松要看需求,如果数据再大一点,能完成而不因为各种内存空间不足报错就是可以忍受的。
@zzNucker 他这是全表扫描,索引并不能提供太多价值。 |
![]() |
14
adoal 2024-01-13 22:06:19 +08:00
因为,很久以前的说法是 MySQL 上了 2000 万就要分库分表……所谓轻松 1 亿是针对以前年代的硬件和 MySQL 版本上 OLTP 类系统哪怕做好索引和优化也扛不住这个量的数据来说的。
|
![]() |
15
liprais 2024-01-13 22:12:12 +08:00
clickhouse 有事务么?
|
![]() |
16
akira 2024-01-13 23:10:33 +08:00
mysql 上亿 只是说能用来做跑常规业务,汇总统计还是要别的来做的把
|
17
night98 2024-01-13 23:39:36 +08:00 ![]() 你说这话不就是纯抬杠了吗,有哪个带事务的行数据库能扫一亿数据统计在十秒内出结果的?你光磁盘 io 都不够这个数吧。 不过也可以做,无非所有数据缓存到内存里,统计也还是很快的,加钱可达
|
![]() |
18
adoal 2024-01-13 23:59:46 +08:00
刚才忽然好奇测试了一下 PostgreSQL ,在自己陈年老机上,i4-4460 ,32G 内存,没 tune 过参数的 PG16 ,生成了一亿条随机数,全表 sum 一下 1972.434 ms
|
19
xiaofan2 2024-01-14 00:00:31 +08:00
其实扫描速度跟你表设计大小有很大关系 我们有一个小表余额表 只保存了独立的几个余额相关字段 单表一亿扫描无任何问题
|
![]() |
20
min 2024-01-14 00:01:00 +08:00
ap 场景用 tp 数据库,被 ap 库秒得渣也不剩
|
![]() |
21
nuk 2024-01-14 00:03:01 +08:00
所以 mysql 到底跑了多少秒
|
22
ntedshen 2024-01-14 00:22:22 +08:00 ![]() 拿列式库在本地查单列。。。
拿行式库不允许索引不允许分布式还要放到 io 差了好几倍的 vps 上跑。。。 得出一个结论至少慢 60%。。。 讲道理,我认为这属于褒奖 mysql 。。。 gp3 的 16kio 是 16000 合 256MB/s 。。。 请注意现在的家用低端固态的 4k io 都能达到 160k 。。。 |
![]() |
23
est 2024-01-14 00:27:53 +08:00
感觉这不是 mysql 的问题,而是 aws 的 IOPS 的锅? LZ 测试 clickhouse 也是 t3.xlarge (4c 16G) 磁盘类型为 GP3 嘛?
mysql 的话,还得调优一下 InnoDB 才有比较好的性能。我 10 年前测 tokudb ,把 qq 那个 10 亿条导入进去,无聊 sum 了一下群号。。 差不多 10 秒就出来。。 |
24
miniliuke 2024-01-14 00:30:35 +08:00 ![]() 求求了用 pg 吧,实测真的吊打 Mysql (未调优)......
|
25
ShuWei 2024-01-14 00:40:53 +08:00
别拿极端情况反驳,毕竟原贴的绝大部分情况下,都不太可能涉及全表扫描,而且,这种全表扫描,很多时候都可以通过冗余统计字段的方式来温柔对待,因地制宜就好,在需求和成本间实现优雅的平衡
|
![]() |
26
xmh51 2024-01-14 00:48:56 +08:00 ![]() 大哥,我们只是提建议,不是你用来抬杠的对手。
Clickhouse 没有完整的事务支持。 缺少高频率,低延迟的修改或删除已存在数据的能力。仅能用于批量删除或修改数据,但这符合 GDPR 。Clickhouse 适合海量数据,低频更新,低并发查询。尤其是统计数据。 mysql 是一个传统的支持完整事务的数据库。 两者不在一个赛道上,根据自己的需要自己决策选型。 |
![]() |
27
LeeReamond 2024-01-14 00:56:12 +08:00 ![]() 听别人说有什么用,你每天混论坛的还不知道大部分人是啥水平。所谓轻松能跑出来就算轻松,一个查询 5 秒,只要用户没 call 过来说慢那就是纯正常响应速度。
楼上的也不知道有几个试过,一亿级数据就算用唯一索引,单行数据调取性能下降多少,a<索引<b 查询多长时间才能返回,分区后能不能加速。 反正我试完上述结论没一个显示能用的。 当然这是单实例,你集群虚拟化数据层当我没说。。 |
28
mysunshinedreams 2024-01-14 06:12:48 +08:00
之前工作经历有过单表上 10e 数据的,不过仅存了包含主键在内的四个字段,也是在不断往上探测系统极限性能的情况下才发现瓶颈的,某些特别场景还是可以抗住的。
|
29
NXzCH8fP20468ML5 2024-01-14 07:42:34 +08:00 via Android
v2 的人谈数据库,基本上都是在赛博斗蛐蛐。
不会有人不知道 mysql 一个查询只能用单线程吧。 这也是为什么一群人吹嘘 oracle 大表连接很快,又有人吹嘘 pgsql 可以平替 oracle 的原因。 因为其他数据库的一个查询可以利用多个核来执行,mysql 还在煞笔的用一个核去跑,不慢才怪呢。 |
30
fd9xr 2024-01-14 08:41:21 +08:00 via iPhone
5.5 都随便跑…到底哪里不行了 是什么要让你在里面算 SUM()
|
31
W3Cbox 2024-01-14 09:03:28 +08:00
什么样的业务会有上亿数据。从事开发年 10 来,很多公司从创业到倒闭了都没有上亿数据,真有上亿数据,公司都可以上市了
|
![]() |
32
xuanbg 2024-01-14 09:45:13 +08:00
3000 万+,6 表联查,平均 50ms 。
|
![]() |
34
june4 2024-01-14 11:05:41 +08:00
@LeeReamond 有索引还会慢?你要不要了解下索引的原理,走索引百亿内无论多少数据都只要固定的小量读硬盘次数。刚在我的亿级表上试了下,无论是取单行还是 100 行,在索引上耗时显示都是 0.000s
|
![]() |
35
goodryb 2024-01-14 11:19:49 +08:00 ![]() 查了下 aws GP3 的性能参数 每个卷的最大 IOPS (16 KiB I/O) 16,000 , 每个卷的最大吞吐量 1,000 MiB/s
这个速度怕不是连我台式机上面的 pcie3.0 ssd 都打不过,对数据库好一点吧 https://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/ebs-volume-types.html |
38
NXzCH8fP20468ML5 2024-01-14 12:18:26 +08:00
|
39
FishBear 2024-01-14 12:23:33 +08:00 via iPhone
我们公司的表 12 亿了还在跑
|
40
yh5DC6Y7u7TdcT9s 2024-01-14 12:29:24 +08:00
oltp 场景: 典型代表 pg 和 mysql ,使用范围最广,常见 web 业务,日常增删改查,支持事务的 ACID 特性; 通常查一整行数据或者多列,基本不会全表扫描,所以数据底层按照行来存储数据,读一整行时按照局部性原理,会对缓存友好
olap 场景:典型代表 clickhouse ,doris ,hbase 等;常用于分析统计,需要大量扫描数据,且通常只关注某一列数据,不支持事务/支持的很弱,底层数据是按照列来存储的,因此扫描列的效率远大于扫描整行 两个不同的赛道, 底层设计都不一样 |
41
jeesk 2024-01-14 12:56:20 +08:00
没有相同的条件,然后不同的人会得出不同的结论.
你说的上亿的数据? 机器什么配置? 磁盘,cpu ,内存, 等等. 我个人觉得网络上的评论多数是不能信的, 还是要自己实践. 就像 windows 有说卡一样, 1 个人还在用 8 代低压 cpu 的笔记本,另外一个人用上 13 代 i9 cpu. 1 个人说卡的要死, 另外一个说流畅的要死? 怎么评价? 他们说的都是真话. |
![]() |
42
iyaozhen 2024-01-14 13:49:29 +08:00
哥,谁叫你全表 count/sum 呀,不加 where 就是很慢
数据库场景分两种,oltp 、olap ,简单来说就是 oltp 主要是 select * from table where id = xxx ,1 亿肯定没啥问题。olap 就比较看场景了,比如统计一天的 pv 、uv ,select count(*) as pv, count(distinct user_id) as uv from table where `date_day` = '2024-01-01' 这样也行,好几千 w 的表也可以秒出,如果 where 条件不能命中索引就麻烦了 MySQL 是通过不同存储引擎来分别支持两种场景,但实际情况是两种场景我们都有,这就出来了 tidb 这种 newsql ,两种都支持的比较好 我实际搞过,当然公司不缺资源,100C 256G 3T SSD |
![]() |
43
allenzhangSB 2024-01-14 14:31:02 +08:00
@adoal #18 方便同样的数据用 MySQL 再跑一遍吗
|
![]() |
45
LeeReamond 2024-01-14 16:48:09 +08:00
|
![]() |
46
litguy 2024-01-14 17:36:17 +08:00
GP3 的性能感觉不太行
虽然一个 NVME 盘性能都可以爆掉它了 可能那些用户配置和你不一样 |
47
hefish 2024-01-14 17:39:00 +08:00 ![]() php 是最好的语言,没有之一。
|
![]() |
48
Foxkeh 2024-01-14 17:43:35 +08:00
请问主题里这个场景里所有的 cost 字段都是动态的吗?有没可能按照时间区间或者其他维度定期计算然后只做累加?
|
49
icy37785 2024-01-14 18:31:00 +08:00 via iPhone
@W3Cbox #30 我的个人项目手机百度网盘的分享链接做搜索,数据都是以亿为单位了。以前数据上亿少很多就是因为性能问题比较省,真放开手来,很多类型的数据都是很容易过亿的。
|
50
Terry166 2024-01-14 20:12:07 +08:00
既然是在 AWS 上,可以试试 Snowflake ,AWS 上的数据仓库平台,把数据库文件导入 Snowflake ,查询的时候会自动横向扩展提升查询效率,查询包含 1000 亿条数据的表也只需 10 秒左右的时间。
|
51
nnegier 2024-01-14 21:16:38 +08:00 via Android
@j1132888093 #4 在这样的环境下为什么索引快呀? 1 亿条
|
![]() |
52
me1onsoda 2024-01-14 21:21:01 +08:00
有没有可能你配置太抠了
|
![]() |
54
RangerWolf OP |
![]() |
55
RangerWolf OP @miniliuke 也想转试试看,老项目的路径依赖比较强一点,新项目可以试试看
|
![]() |
56
coinbase 2024-01-15 07:48:06 +08:00
pg 是最好的语言,没有之一。
|
![]() |
57
Narcissu5 2024-01-15 09:01:35 +08:00
OLAP 的角度来讲,20S 可能真的不算慢,我司之前的大数据开发用 hive ,随便一个查询至少两三分钟
|
![]() |
58
rickiey 2024-01-15 09:26:05 +08:00
云存储应该有 iops 限制
|
59
crazycarry 2024-01-15 09:28:11 +08:00
70 亿的三个表。。只能索引查询。。。
|
![]() |
60
jowan 2024-01-15 10:17:00 +08:00
你这里是 count 全表,除非是业务统计需要,我们的投放平台监测链接和媒体回传表几十亿,业务上要做取舍,和淘宝京东类似,你检索结果几百万但最多只给你展示前 N 页。根据那个帖子的介绍,在以插入和简单查询为主的场景下 MySQL 完全够用,确实轻轻松松。而且我们还有复杂的统计查询,不过业务上都是要求带时间范围,比如最大时间跨度不能超过 3 个月,等等。
|
![]() |
61
jowan 2024-01-15 10:19:29 +08:00
MySQL 的 count 性能众所周知,几百万以上就特别明显,数据量达到千万级别后要么你用预估统计 TABLE_ROWS 之类的,要么就缓存。而且条件查询一定要命中索引和限制返回行数,要不然崩的概率非常大。
|
![]() |
62
hallDrawnel 2024-01-15 10:21:34 +08:00
同时要看你买的什么配置的 MySQL ,跑在什么硬盘上。我们之前几亿的数据常规业务操作基本 100ms 以内完成。
|
63
keshawnvan 2024-01-15 10:42:01 +08:00
试试 PolarDB ,开列存节点,实测复杂查询快 30 倍以上。
|
![]() |
64
lbunderway 2024-01-15 10:49:38 +08:00
我一般是超过 800 万就要分表,但是这个分表时机要看索引长度和树的高度决定
|
66
javaisthebest 2024-01-15 11:17:35 +08:00 ![]() |
67
leonhao 2024-01-15 11:29:08 +08:00
V 站数据库的水平怎么这么低啊,讨论其他的头头是道,到了数据库就特别拉胯
|
![]() |
68
Mrun 2024-01-15 11:33:56 +08:00
我现在手上的业务,单表都有 3 亿+的,要看的 sql 的复杂度的。。。
|
69
luckywh 2024-01-15 11:37:45 +08:00
一亿五千万 count 主键 平均 5 秒 mysql 生产环境
|
70
laaaaaa 2024-01-15 11:42:56 +08:00
我们一般上百万就上 es 了- -
|
71
kestrelBright 2024-01-15 11:46:22 +08:00
看扫描行数,还有行数据大小吧
|
72
yumizhao888 2024-01-15 11:54:42 +08:00 via iPhone
一看大部分就是理论家,数据库就存储用的,放那么多单遍是想显摆自己技术牛逼吗?一看就是学生党。实际上手就是能 select 就 select ,能分表就分表,索引一下,要什么数据程序判断一下 1ms 不就马上出来了吗。
数据库很难吗??? |
![]() |
73
encro 2024-01-15 12:03:54 +08:00
统计 mysql 这类数据库的一个老大难。特别是加了 where 的统计。所以最好的做法是避免统计。
我就是一个表放几万数据的,但是我不会给他们实时统计的,他们要的报表是每天生成的,不能修改的。 |
![]() |
75
MaxFang 2024-01-15 12:28:32 +08:00
上 r6 4x 的试试。
|
![]() |
76
zpfhbyx 2024-01-15 12:32:36 +08:00
上 e 的表本身搞统计就是跑不动啊. 轻松的话 一般说的都是主键 id 或者主键 id 偏移+ 区间的扫描啊. 比如 select xxx from test where id > 0 and id <= 100000 这种
|
77
sampeng 2024-01-15 13:25:22 +08:00 ![]() 说的轻轻松松是有前提条件的。仅仅是业务查询,非聚合查询。聚合分析别说上亿了,上千万,可能就得考虑上 olap 的分析工具了。
另一方面,你都上亿的数据了,还是需要分析的。4c 16G 是不太小了点。这个成本是可以计算的。 1.clickhouse 集群。4*16 集群 x3. 2.mysql 把硬件往上面拉三倍。 从哪个角度看都是 2 成本更低。除非你能做到 1 是动态的,但投入的隐形成本又是另一回事。 换句话说,我个人认为绝大多数的场景,堆机器就够了。除非有数据分析团队资源,全靠研发自己出方案,实在得不偿失 |
![]() |
78
ewBuyVmLZMZE 2024-01-15 13:44:03 +08:00
@djangovcps #3 他这种数据需求,不如上 ClickHouse 了,ES 在这块的加成不如 ClickHouse 。
另如果是 sum 之类的这种 Analytical 的查询,写入量不高,存量高,需要实时更新的话,可以预聚合写入。那种情况下,ClickHouse 加物化视图很不错。 |
79
NoNewWorld 2024-01-15 13:48:19 +08:00
全表..... 百万就不行了,上千万的查询只有建立在索引能筛选掉大部分数据的情况。
|
![]() |
80
j1132888093 2024-01-15 15:29:57 +08:00 ![]() @nnegier 拿我前公司的业务举例,1 亿条数据的表,根据公司 id 哪怕只走一级索引,过滤出来的数据其实已经是千分之一乃至万分之一了,再拿这几千个 id 去走主键索引,四层的 B+ 树查找在目前普遍用 SSD 的情况下,还是可以接受的
|
![]() |
81
Vegetable 2024-01-15 20:29:14 +08:00
由于看不惯别人装逼自己发帖结果让别人又装了一遍
|
![]() |
82
RangerWolf OP @Vegetable 人艰不拆好吗
|
![]() |
83
adoal 2024-01-16 14:48:54 +08:00 ![]() @allenzhangSB 我上次拿来测试的物理机系统是 Debian 13 ,MySQL 官方 deb 包只到 12 的,库依赖有问题,我又懒得自己编译了。今天找了一台 Debian 12 的虚拟机做了测试。所在的物理机也比较老了,E5-2360 的。虚拟机是 6C 12G ,存储是来自 SSD 加速的 HDD 阵列分的 LUN 。
安装了 PG 和 MySQL ,PG 来自 PGDG 的 apt repo ,版本 15.5 ,MySQL 来自 Oracle 官方 deb ,版本 8.0.35 。两者都没做任何 tuning 。 测试数据:先在 PG 上生成,再导出后导入到 MySQL 去。 数据生成语句: create table t(i integer, v integer); insert into t (select i, random()*100::integer from generate_series(1, 100000000)); 测试语句: select count(1) from t; select sum(v) from t; select v, count(1) from t group by v; 测试一个系统时关掉另一个系统。不过没重启服务器。 测出来的结果 pg15 count: 2.746s sum: 3.001s group: 7.109s mysql80 count: 4.67s sum: 76.48s group: 100.95s |
![]() |
84
woshicixide 2024-01-16 19:54:45 +08:00
可能是指按主键查询吧
|
85
zzmark06 2024-04-03 16:47:58 +08:00 via Android
oltp 业务,时间和扫描数据量基本成正比
你这个,扫描数据量上亿,咋个快法? olap 业务,时间和扫描数据量也是成正比,不过可以通过只扫描必要列、并行扫描多 chunk 并行加速、跳数索引(减少 chunk 数量)、预聚合(无需扫描原始数据)、块压缩(减少 io 时间)等手段来变相超车,减少实际扫描数据量。 分库分表,若依旧单并行顺序执行,不过是把工作拆分,最终时间不变(不考虑 cache)。 若并行查分表,那就是上面的多 chunk 并行加速。 新些的库,比如 polardb ,不开 imci ,只选择并行化,也可以实现相同的效果 mysql ,一些统计性质的聚合函数可以通过索引,能实现类似于“只扫描必要列”的特性 至于你举例这个 sql ,除了有列存优化的库,应该谁跑都差不多才是,都慢 |