面试最后一问把我整懵了
今天面试的最后一道问题。
内容是做年度数据报表,千万级的数据量需要在屏幕上分页展示。目前问题是查询太慢该如何解决。 我的回答是加索引。结果面试官的回答是:“还是慢。”把我整懵不知道怎么回答了。解决查询慢的关键真的不是索引吗?…
在此求教万能的 V 友们 (:з」∠)
今天面试的最后一道问题。
内容是做年度数据报表,千万级的数据量需要在屏幕上分页展示。目前问题是查询太慢该如何解决。 我的回答是加索引。结果面试官的回答是:“还是慢。”把我整懵不知道怎么回答了。解决查询慢的关键真的不是索引吗?…
在此求教万能的 V 友们 (:з」∠)
解决关键:减小 offset 的值。
解决方案:
1 、排序再查询 / where 语句后查询(通过各种手段把 offset 变小)
2 、分表。(业内流行 500w 一分)
3 、缓存
上述言论如果有错误的,望指正
这个数据规模下,表分区,分表,分库就成了基本考察点,但是线上具体用法则会有些差异的地方,这个部分不会是面试官的考察重点
面试官问这种问题基本就是考察
1. 你有没有遇见过要翻几百万页的需求
2. 你当时的解决方案是什么, 因为数据库直接 limit 1000000,10 是跑不起来的
这个时候就要更深入问具体需求究竟是什么, 从中分析可行方案
如果他也不告诉你,那你就把你自己认为最好的方案写出来就行了啊,或者你先写一个简单方案,然后逐步优化它,体现你的思路。
流水数据分页查询,物理机顶配刀片,全固态盘,数据库 mysql,单表 3 亿+数据,有交易时间分区,复合主键,没有自增 id(别问我为什么没有自增 id,我也很想问当初的设计者)
在多次优化 sql 无果后,果断停机拆表加自增 id…
复杂方式:
1 、分表
2 、通过 mycat 做中间层
不就完事了
贵族方式:
另外,阿里云出了个 DRDS (很贵),只要有钱,能有啥性能问题
—————————————————
另外,加了索引不一定命中了索引,命中了索引不一定会快,要留意 explain 的 type 和 extra,如果出现 using filesort 和 using temporary 照样得跪,这个时候都会反问面试官,加了索引一定命中吗,命中了效率一定快吗?
如果真要认真地问这个问题,
首先当前是怎么实现的,具体是个什么查询,慢是有多慢,预期要达到多快的速度,对数据的实时性要求有多高,这个报表有多高的查询频率,开发这个报表愿意付多少成本,运维这个报表愿意付多少成本。
这些都得先说清楚,根据不同的情况显然可以给出很多种不同的方案。
通常这类问题的解决方案都是折中的
比如上亿的数据 模糊搜索 那显然用 es 比 mysql 好 (不需要事务)
比如加载到特大内存,快速查询 (特有钱)
比如预先计算, 缓存预热
比如分表分库
具体问题具体分析
有相关经验还能问问是不是 xx 导致的,没经验只能干瞪眼
有些提问就纯属抬杠,
分库分表他说慢
说分布式集群 他说有可能全挂掉
异地多活 他都能说网线断了
你这问题就提供了两个点 慢 年度数据报表
报表一般来说 可以先算好的
慢 到底是慢在哪里
就是找痛点 找瓶颈
如果放到更高一点层面来说,一般还会有下面几点。
1. 分布式 /分库分表与数据归总。
2. 缓存。
3. OLTP 与 OLAP 差异,列存数据库与行存选择。
1 、硬件配置
2 、数据建模的时候 根据查询需求特点做优化
3 、合适的索引
4 、查询语句优化
5 、加缓存
6 、分表、分库、读写分离等
千万级数据,是个很有意思的数据量。往小的说,64 位 ID+64 位数据再加一个简单索引,撑死就几百 M 的非关系型内存数据。如果设计成流式统计或固定数组 + 矢量更改表,以内存高达 G 级与每秒海量 IOPS 的处理速度,查询与分页时间能在 ms 级完成。但如果往大的说,把满载撑死的单行平均数据,非顺序的链式(乱跳)结构,各种强关系的牵扯,各种触发器的拖累,加上数据存储在每秒 iops 低于 1k 的低速机械硬盘里,以及单次查询限定了非常小的内存空间,那么一次查询的排序 + 处理,能耗上两三小时也说不定。
这种情况下,面试官说不定早就针对他们自己的情况,给出了优化程度相当高的方案,然后在不告诉你完全信息的情况下,让你猜他们的场景与算法。他这种行为,面试很有可能已经不是他的唯一目的,说不定是他在同事面前故意刁难面试者,来哄抬他自身的技术价格。如果被面试者的级别越高,他就能越得逞。此时,就算你中了大奖,完整地猜出他们的场景,并给出了优于他的方案,说不定他也会一口否决你,然后说你的方法不行。
避免这种非对称羞辱的最佳方法,是你在面试前,针对他们产品的某种特性,给出更好的解决方案,并且提前做出性能对比测试并得出报表。此时,你完全可以不回答这个问题,然后直接扔出你的报表,说要不录用,要不你换公司,甚至换到竞品公司。当然,如果面试时,面试官很厚道,你可以保留这个行为。
我做过 20 亿条单个表的数据库。其实以主键排序 20 亿并不会慢。而索引的问题在于,如果加索引的列有大量重复的值的时候,索引是无效的。所以一般索引只对主键,或者时间戳比较有效。这个时候要么分表,要么上 elasticsearch 。都是挺好的解决办法。
就说经典的面试问题,如果用户输入了你的网站地址,按下回车,但是网站迟迟不加载,问题在哪。你不去一步一步分析场景缩小范围找到问题点,坐在那里傻瞪着面试官,那人家不拒你留着过年么。
索引、缓存、分表。
根据 id:select * from (select id from 表 limit xx,xx) a left join 表 b on a.id = b.id
可能确实是我表达不当,“加索引”不是我回答的全部。我想表达的意思是,我提出的“加索引”、“分库分表”这些解决方向没有像预期的那样得到正向反馈。
确实也是经验不够导致的吧。当时的状态过于被动,说完自己想法之后就在等面试官能给点提示。如果能沉住气去追问然后再给出别的解决方案应该会得到更好的结果。