上万条数据, 短时间内连续查询几千次, 是数据库查, 还是内存查更好一点?

249 天前
 bthulu

客户库存有一万多, 要将这一万多库存按客户要求分散到几百个工位上, 需要针对库存的多个属性进行多次查询, 循环里套循环, 能查上千次甚至更多.

这种情况下, 我是直接数据库查, 还是将数据一次全拉到内存, 在内存里查更好?

数据库查可以走索引, 内存里可就没索引查一次就是全量遍历一次了. 如果有内存里支持索引的列表就好了. 语言是.net8.

别说什么优化查询方案一次查询搞定的了, 这不可能. 现实业务就是各个工位之间关系也是错综复杂, 只能这样查了.

9167 次点击
所在节点    数据库
76 条回复
shenjinpeng
248 天前
Mysql 做好索引, 开启查询缓存, 使用 chunk 或者 游标 cursor 查询, 每次多查点 , 使用连接池 , 需要并发的话可以使用协程
tearsinchina
248 天前
redis
RangerWolf
248 天前
1. 目前如果优化数据库索引设计是否可以达到你的要求?
2. 如果各种优化了还是达不到性能要求,上 Redis 大概率是一个不会错的选项
不一定是最优解,但是大概率不会错。
3. 底层是 MySQL 的话,别太期望 Query cache(这玩意默认应该是禁用的)

我的思路跟理念:
能少一个模块就少一个模块,维护成本压到最低。

以 Redis 为例,Redis 数据的更新策略? Redis DB 自己的维护成本如何?是否熟悉 Redis 数据迁移?
所以,不要一开始就 over design ,建议先尽量优化数据库设计(也是对技术深入研究的一个自我要求)
RangerWolf
248 天前
@shenjinpeng 兄弟,查询缓存默认被关闭应该是有原因的,可以研究看看是否真的适合自己的业务场景再开启
dif
248 天前
参考 Hive 和 Impala ,第一次查询时比较慢的,尤其是刷完元数据以后,但查询一次以后,就比较快了。 你就参考这两个设计就行。
yyyyyyh
248 天前
如果数据库和应用服务器是同一台服务器 , 就用数据库。 原因因为你的数据结构不是单纯的 k-v ,利用数据库的索引更好的实现查询。 放在内存里的开销也没有想象中那么低 ,几万条数据,可能要经过几次查询遍历,相当于循环几万次。

如果不是同一台服务器,还是建议内存吧,不然就算数据库很快,最基本的网络 IO 开销都挺大了 ,可能最简单的查询都需要 10~20ms
zephyrzdf
248 天前
@bthulu
数据存数据库,数据量很小,又是定时任务,实时性不高,没必要放内存,不会慢,稍微慢点问题也不大。
业务复杂要考虑的是业务代码的可读性,可维护性和可扩展性。
可以考虑按照业务模型做缓存,防止重复查询的频繁查库即可
whusnoopy
248 天前
上万条数据真没多少,担心 DB 没有索引或有远程网络调用开销,读到内存里来,每次遍历这个 O(n) 的 n 也不过 10K+,相比内存访问带宽和 CPU 处理能力,完全不用看

假定上万条是 10 万条数据好了,这就是 100K ,每条数据占 1KB 内存,那也就是 100MB ,普通的 PC 机还能挪不出这 100MB 的内存来?

具体还是要看业务场景,是同机器上的数据库还是不同机器提供的数据库,数据检索是单条件还是多条件,带不带索引,建索引和维护索引的成本,查询条件更大概率是方便 SQL 化的还是方便代码实现的
coderzhangsan
248 天前
如果只是 1 万多条数据,数据库查询完全就能解决,你需要的是如何拆解业务逻辑做到最优化的方案,例如业务查询分组等等,使数据库查询代价最小。
sockpuppet9527
248 天前
提一个可能大家都没注意的点:page cache + 数据库 cache 。

实际上短期大量查询大概率都是在 cache 中的。如果觉得内存中操作太麻烦了话,还是考虑走 db 把。
zephyru
248 天前
这个数据量并不多...几百万的数据 sqlite 在树莓派上,做这种关联查询单次也能压到几百 ms 内...
不过看描述感觉是先用一次查询获得下次查询的条件,进行嵌套查询,其实很多时候自己写各种数据结构算法还真不一定有数据库或者语言自带的数组便利好用,建议在实际运行的环境下试试再说
jorneyr
248 天前
普通单机 MySQL 每秒可以查询 1 万多次。
whitedroa
248 天前
怎么楼上这么多菜鸡。
先说结论: 如果要查询一千多次,肯定是先全查出来放到内存里啊。
你知道 1 千多万次遍历要执行多久吗?不会超过几毫秒!
每次去 mysql 查,网络耗时有多久???
所以这还用比较吗
barbery
248 天前
内存表?
1018ji
248 天前
mysql 不是有内存表,再找找其他的呗,同步就是了
kandaakihito
248 天前
我现在在做的一个项目就跟你比较像,不过数据量比你还要大上十几倍。

这种数据量看着对于现代数据库来说不算什么,但是能保证后面实际业务过程中数据量不会增加吗?
确定不会有多个用户同时操作?
确定其他模块不需要如此大量读写数据?
确定其他模块不会调用这种大数据量的方法?
能确定实际部署的时候,客户的服务器不是石头盘或者数据库玩拆分服务器 cpu 跟得上?

直接放数据库在硬盘读写的话大概率后面用户体验很差,或者只能把这种方法写成异步处理,但是业务流程得小改。
janwarlen
248 天前
@q727729853 #8 查询次数太多了,会有额外的 IO 耗时消耗
watzds
248 天前
我自己没试过,可以考虑这种,读取一次 mysql 数据到本地内存数据库,内存数据库也可以建索引,之后查内存数据库

比如:sqlite 内存模式 memory 索引
kandaakihito
248 天前
而且不知道你们交付的时候有没有压测流程,到时候运维找上门问为什么硬盘 IO 资源打满了就有趣了
watzds
248 天前
另外这个 cqengine 看着也不错,可以快速查询的集合


https://github.com/npgall/cqengine

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

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

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

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

© 2021 V2EX