1、在没有索引的情况下,怎么从千万级数据库快速筛选一条数据
2、定时任务是定时从数据库筛选数据执行业务,但是当数据库没有符合的数据时也在定时的轮序查数据库,这样会很耗系统资源,怎么解决
第一题的条件是 身份证号,姓名,性别三个字段,根据身份证筛选,表的数据有一亿,但是没有索引也不能加索引
之前有人说过用布隆算法,没了解过
没有索引总有一个自增主键吧, 主键默认是有一个聚索引的, 把数据库记录看成一段一段的1-100W, 100W-200W, 这样把没有数据这些段记录下来, 下次只查找有数据的段
面试官说啥都木有
@灬丶: https://learn.microsoft.com/zh-cn/sql/relational-databases/indexes/heaps-tables-without-clustered-indexes?view=sql-server-ver16
堆表的目的是快速插入, 查询还是需要建立非聚集索引的, 所以如果不是面试官理解错误, 就是你这里陈诉错误了..
或者就是你说的用布隆过滤器, 但是这个要依赖第三方而不是数据库
第一题太笼统,查询条件是什么?数据格式是什么样的。主键也没有索引?
第二题好搞,做一个标记,标记哪个表可轮询,那个表不可。这个标记的修改时机是执行delete、insert、update时
第一题的条件是 身份证号,姓名,性别三个字段,根据身份证筛选,表的数据有一亿,但是没有索引也不能加索引
之前有人说过用布隆算法,没了解过
@灬丶: 是关系型数据库吗?
@会长: 是滴
@灬丶: 除了分表没想到什么好办法?你最后没问下面试官?
1、分表分库具体可以上网查询。
2、定时任务基本不可能在正常业务时间进行,都是事先查出数据存起来需要的时候直接展示就行。
1、如果是从千万级的表中,取一条数据,没有索引之类的,我觉得,你使不上什么技巧,因为没有技巧给你使。
但是,如果只是说从千万级的数据库中,取一条数据库,唯一的办法也只是分表,把人员分100个表,理想情况下,只能减2个数量级,从千万级变成十万级。但是多出100张表的代价,这个在工程上比较傻帽。
2、这个是直接的办法就是,加一个状态位表示是否处理过,设置为索引,每次扫这个玩艺,效率基本接近极限。如果不能加字段,那就加触发器,把新写入的数据的主键,记到另一张表中,去扫那张表,处理完删除掉。又或者,原来就有时间戳的话,设置为索引,直接扫它。诸如此类。
除了分表没想到什么好办法?你最后没问下面试官?
看到 2L 答复里的 反对
笑了
为什么会有人点反对?
回答有问题吗?谁规定了面试过程,只能由面试官提问?
另外,稍微正常点的 面试官
或 流程
都会有反问环节,你不主动找对方答疑还指望别人喂给你不成?
没有问下面试官挺遗憾的,因为并不清楚限制是什么,比如可不可以借助其他中间件。
分表是一种解决方案,还有一种方案是利用es,因为身份证的每位数字都是有一定的对应关系的,省市区,出生年月。依据这些信息可以建立不同index,比如按照省市地区来创建index,刷入数据,或者按照出生年份创建infex,刷入数据。存储在ES中的唯一好处就是查询速度很快,缺点是要做好足够的安全措施,查询语句比较麻烦,如果是数据库,ES双写,维护麻烦,如果是定时任务刷入,会相对简单,但是实效性不如双写。两种方案我们都有做过,最终使用的还是数据库ES双写,业务场景主要是快递服务,使用的是地区做为索引。
第二题楼上的几位都给出方案了,其实就是redis缓存+钩子。将定时任务数据存入到redis中,并在redis添加过期时间以及是否需要更新的flag字段。比如你过期时间设置2小时,定时任务默认20分钟执行一次,定时任务先查redis的flag字段,如果这个字段是false,则不做轮询操作,甚至可以延长过期时间。当你数据库做insert,update,delete操作时,也对redis的flag状态做更新,那么下次定时任务就删除该数据,重新查询并存入redis。过期时间是为了强制保障规定时间内做一次查询,用不用看具体业务场景,用不着就设置过期时间长一点。