我想把现有 ERP 系统的查询功能进行优化
目前的情况是有 4 张主表, 每张表大概有 1500w 条数据 ,每天大概增加 3w 条数据, 每张表都有 100 多个字段,其中不乏有 varchar(200)这种字符串.
查询时 4 张表还会进行 join,算上其他表总的关联表大概有 10 张左右.并且查询条件也比较多变,聚合索引难以覆盖所有场景,但一般会基于一个时间段再搭配其他三个灵活的字段进行查询.
目前的想法是把这几张表的数据进行聚合,筛选出比较重要的字段(大概有 70 个)单独存放到一个数据库中 , 以下是我的一些需求
目前是把数据放到了 MongoDB ,加上索引后大概占了 20GB 左右,查询效率一般, 所以想知道对于我这种场景有没有比 MongoDB 更合适的数据库, PostgreSQL ClickHouse Cassandra ?
![]() | 1 jmone 2021-08-12 02:37:27 +08:00 以前我们使用 mongo,2000 万左右的数据,索引后,数据查询时平均 500ms 的响应时间,然后就放弃使用 mongo 了 |
![]() | 2 pengtdyd 2021-08-12 06:22:28 +08:00 这么多表 join 应该考虑重构 |
3 lixm 2021-08-12 08:45:19 +08:00 ES 啊 |
![]() | 6 encro 2021-08-12 08:57:53 +08:00 ![]() 没有必要 mongodb 吧,mongodb 只是一个文档型数据库,并不会帮你提高性能。 看你对实时性要求和查询范围, pg 有物理视图和聚合,是否能满足要求? 我们有一个项目也是几千万数据。 我是限制了默认查询时间,在时间上加了索引,比如只查询最近一天或者一周的。这样数据就几万几十万,还是很快的,一般 50MS 能出来。 对于复杂的,要查询 2 个月以上的,都走统计表,统计表为增量,每 5-15 分钟执行一次,所以不是实时的。如果你团队人力比较充沛,可以用自动聚合,做成实时的。 |
![]() | 7 JKeita 2021-08-12 09:17:49 +08:00 一张表 100 多个字段,这个设计真是鬼才。。。 |
![]() | 8 JKeita 2021-08-12 09:30:43 +08:00 感觉 ES 就够了吧 |
![]() | 9 wangyzj 2021-08-12 10:08:16 +08:00 数据库不要变 ERP 这种强关系型还得用关系型数据库 可以做一个同步到 es 的作业 只做查询 mongo 不合适 |
![]() | 10 speedofstephen 2021-08-12 10:12:52 +08:00 时间段是多长呢,如果一天就 3 万,只某一天 或者更小的区间搜索。直接用时间段过滤 然后用 java 的 stream 做筛选。应该不会超过 100ms 把。 |
11 Pursue9 2021-08-12 10:18:43 +08:00 可以把包含 json 的字段丢到另一张表中去, 然后主键还用原来表的主键 例如 user (主键是 useruid) 表拆分成 user 和 user_detail 两个表, 主键都是 useruid,什么时候用到 user_detail 的数据时候,再去查 user_detail 的数据 |
![]() | 12 vone 2021-08-12 10:28:35 +08:00 早呀,彦祖。 |
![]() | 13 42is42is42 2021-08-12 10:54:29 +08:00 Get More Row |
![]() | 14 victorywangzhcn 2021-08-12 11:34:46 +08:00 如果没有大量模糊查询的需要,无脑选 ClickHouse,可以测一测。个人感觉 ES 比 ClickHouse 更难运维,而且如果你有 Aggregate 相关操作,ES 非常硬盘 IO emmmm |
15 Mithril 2021-08-12 11:46:37 +08:00 ![]() 既然一般会基于时间查询,说明你这数据本身就是时序数据,可以考虑时序数据库。 如果要用 ES 的话需要考虑两点,一是你的字符串内容要做分词检索吗?二是你要做聚合统计吗? 如果都不要,只是把 ES 当成速度快一点的数据库的话,那么意义不大。因为你还要考虑 ES 本身的那些问题,得不偿失。 所以现在的首要问题是,你是真的需要用 ES 去加速检索,还是想办法优化你的 MySQL 。 至于其它的,你用 MySQL 和 Mongo 解决不了的问题,不要指望 Pg 和 Cassandra 能解决。时序型数据库的话,还是要考虑上面 ES 那段里提到的问题。你需要做聚合统计吗?还是只做数据检索。 |
16 xx6412223 2021-08-12 15:51:19 +08:00 你这个场景的时间段好像不太适用时序数据库。 这样呢: 按年份或者其他周期分成不同的表,保障单表的数据量 |
![]() | 17 nekoneko 2021-08-12 16:42:13 +08:00 分区分表吧,不用考虑 es,mongo 什么的了 才 20G,直接 redis 好吧 有钱的话上 hana |
![]() | 18 windyboy 2021-08-12 17:37:40 +08:00 有超长字符串的就不合适做关系数据库 初步就是改文档型 当然只是纯粹查询的需求直接上 ES 更好 |
19 MarksGui 2021-08-12 18:20:11 +08:00 100 多个字段,确实牛逼 |
![]() | 20 hayhong123 2021-08-12 20:17:33 +08:00 感觉 ClickHouse 和 ES 都能满足呀 |
![]() | 21 sytnishizuiai 2021-08-12 21:31:26 +08:00 我的人生中超过 2 30 个的都没见过。。。学习了、、、 |
22 zibber 2021-08-12 22:44:20 +08:00 1. 如果有关联查询, 写入到 es 的数据按需要重新整合, es 关联查询性能不行 2. 还有一个更简单的方式, 买阿里云的 analyticd, 同步一份, 多核大内存硬查, 选个 16c, 32c 绝对够用 |
![]() | 23 jwangkun 2021-08-13 09:37:19 +08:00 ClickHouse |
24 zlo309618100 2021-08-13 09:59:48 +08:00 塞到 es 的一个索引里面,然后用主表的 id 作为 documentid. 然后所有的查询打到 es,查出 id 之后再去数据库里面拉 这样就把问题从条件查询转为 id 查询。 不过有坑的点是,es 是 real time,刚插入的数据不能在 100ms 级查出来。 |
25 strict 2021-08-13 16:13:10 +08:00 当然是 clickhouse - 首要的是查询效率高,能满足多变的组合查询条件 > clickhouse 支持超多内置函数&自定义函数 基本上只做即时查询 ,没有对数据进行二次挖掘和处理 > 计算速度快 其余条件 > 全都满足 |
![]() | 26 Brentwans 2021-08-13 19:09:40 +08:00 4 张 1kw 的表之间还要 join ? n 比 n 的 join 吗? |
![]() | 28 changdy OP |
![]() | 29 changdy OP |
![]() | 30 changdy OP @nekoneko 嗯 正在考虑用 shardingsphere 实现分区分表 .不过 redis 就不太行了 单纯的 key value .涉及到条件查询还需要加载到内存中过滤 |
![]() | 31 encro 2021-08-14 17:27:11 +08:00 ![]() 同等配置下,es 性能不会比 mysql 高,预热过后加载到内存中的 es 才性能高。 es 性能高的主要原理是: 1,index 分区; 2,内存预热; 3,搜索引擎倒排索引; 欢迎补充。 |
32 waytodelay 2021-08-14 20:52:17 +08:00 @encro ES 有什么学习资料推荐吗?最近想学习这个 |
![]() | 33 encro 2021-08-15 09:42:22 +08:00 |
![]() | 34 encro 2021-08-17 09:18:26 +08:00 按日期查询, 那么 ES 比较合适的一种选择吧, 可以按年月建立 index,然后查询。 不过,ERP 一般都是依赖数据库,通过触发器,物理视图,统计表之类的提高查询性能。 |
35 whajcf 2021-08-18 13:58:10 +08:00 ClickHouse 慎用, 出现错误数据时删除特别麻烦, 现在云版报表模块咬牙改数据, 本地版已经拉出分支来在换库实现 ... |