今天面试的最后一道问题。
内容是做年度数据报表,千万级的数据量需要在屏幕上分页展示。目前问题是查询太慢该如何解决。 我的回答是加索引。结果面试官的回答是:“还是慢。”把我整懵不知道怎么回答了。解决查询慢的关键真的不是索引吗?…
在此求教万能的 V 友们 (:з」∠)
|  |      1rrfeng      2020-04-17 12:18:45 +08:00 via Android 就说不知道。 | 
|  |      2warlock      2020-04-17 12:19:00 +08:00 缓存 | 
|      3ConradG      2020-04-17 12:20:14 +08:00 我比较好奇这屏幕有多大 | 
|  |      4sunjourney      2020-04-17 12:20:56 +08:00  9 分析业务啊,分离 hot/cold 数据,要聚合的提前聚合了,分组存储,根据查询条件归约 | 
|  |      5Tianao      2020-04-17 12:21:17 +08:00 改模式、换引擎、加硬件。 | 
|      6fordoo      2020-04-17 12:22:13 +08:00 数据报表,报表不都是汇总数据, 千万级? | 
|      7optional      2020-04-17 12:22:20 +08:00 via iPhone  3 分页慢,不能用 limit offset 分页。 用 id 分页 | 
|      8OSDI      2020-04-17 12:23:34 +08:00 加配置 | 
|      9ylsc633      2020-04-17 12:26:19 +08:00 年度数据 都是汇总啊..........   年度按照月份汇总 1 | 
|  |      10loryyang      2020-04-17 12:26:41 +08:00 都在内存里面就不会慢啊,你要是内存放不下就复杂了 | 
|  |      11nockyQ OP @sunjourney 学到了 从这个方面考虑感觉很靠谱 | 
|  |      13wangyzj      2020-04-17 12:28:58 +08:00 这道题可以回答的很开放 但是面试官感觉有限制在了一定的条件内 | 
|  |      14wangyzj      2020-04-17 12:30:03 +08:00  1 或者 select * from table where pkid > 10000 limit 0,50 这种呢 | 
|  |      15nockyQ OP @wangyzj 或许我漏掉了关键因素?主要是我回答了建索引之后,告诉我还是很慢。然后也没做另补充,我就僵住不知道往哪个方面去回答了。目前这些条件下感觉只有建索引这种“空间换时间的方式”去实现。 | 
|  |      16GBdG6clg2Jy17ua5      2020-04-17 12:38:18 +08:00 via iPhone 面试官显然目前是遇到这个问题了,你应该详细问下更具体的需求,一步步和面试官探讨。解决这个问题了,你就应聘上了。 | 
|  |      17index90      2020-04-17 12:42:34 +08:00 lz 有没有试过 skip 几万条数据,有多慢? 正确答案是改用 seek limit 方式。 | 
|  |      18xmge      2020-04-17 12:43:21 +08:00  1 自我感觉问题关键:这个问题的关键是分页查询时,当 offset 过大时引起的性能问题。 解决关键:减小 offset 的值。 解决方案: 1 、排序再查询 / where 语句后查询(通过各种手段把 offset 变小) 2 、分表。(业内流行 500w 一分) 3 、缓存 上述言论如果有错误的,望指正 | 
|  |      19binbinyouliiii      2020-04-17 12:43:29 +08:00 根据日期分表 | 
|      21tabliu      2020-04-17 12:44:23 +08:00 分析型数据库,Greenplum,横向扩展,直接堆机器,想多快就多快 | 
|  |      23Juggernaut      2020-04-17 12:47:53 +08:00 千万级的数据一条条展示在屏幕上,意义何在? | 
|  |      24opengps      2020-04-17 12:50:02 +08:00 via Android 这问题问得很泛,能回答的方面就是,合理的索引,表分区,分表,分库等一系列技术的组合。 不过看起来更像是面试官的问题自己解决不好再像外界求助 | 
|  |      26nockyQ OP @Juggernaut 面试不总归要造航母的。你说是不是。 | 
|  |      27JJstyle      2020-04-17 13:01:50 +08:00 via iPhone 什么样儿的表结构,什么样的 sql 查询,能否用 es,分表分库可以吗,读写分离可以吗,上更刚的服务器试试呢,能缓存吗,如果还不行的话你们能给我 30k 吗 (手动🐶 | 
|  |      28greatbody      2020-04-17 13:03:52 +08:00 诊断性信息收集了解一下,询问面试官我们现在很慢,有哪些现象?我可以用调试工具看看实际执行情况么? | 
|  |      29DelayNoMay      2020-04-17 13:05:01 +08:00 具体需求,具体分析 | 
|  |      30itskingname      2020-04-17 13:06:44 +08:00 这种问题,一般是面试官前两天刚刚做了这个任务,个人感觉自己的解法非常精妙,所以拿来问你。 | 
|  |      31opengps      2020-04-17 13:07:14 +08:00 via Android  1 这么多楼层,大部分都没意识到问题重点所在,我有过线上单表 15 亿行数据经历,透漏个数据,来重点说下慢的原因:总共 500g 数据的表,索引占了 100G,所以即使索引合理,SQL 合理,表的查询也同样很慢 这个数据规模下,表分区,分表,分库就成了基本考察点,但是线上具体用法则会有些差异的地方,这个部分不会是面试官的考察重点 | 
|  |      32CStarter      2020-04-17 13:13:47 +08:00 via Android 搞一个新表或视图,后台定时跑报表数据汇总写入此表,要用时直接查这个表。 缺点:数据实时性差一些 | 
|      33Jooooooooo      2020-04-17 13:28:36 +08:00  1 首先你要知道大分页是无解的问题, 要明确这一点然后寻找其它妥协方案 面试官问这种问题基本就是考察 1. 你有没有遇见过要翻几百万页的需求 2. 你当时的解决方案是什么, 因为数据库直接 limit 1000000,10 是跑不起来的 这个时候就要更深入问具体需求究竟是什么, 从中分析可行方案 | 
|      34fanyingmao      2020-04-17 13:31:35 +08:00 via Android 我看了下我最大的日志表 3 亿多条,加了索引,好像也还好。 | 
|      35huntcool001      2020-04-17 13:51:04 +08:00 1.分表分库 2.用 ElasticSearch 3.看具体业务,一般有默认展示哪一页什么的吧? 比如说查询最新页面,把最常用的优化一下. 不可能直接 limit 到最后一页去 | 
|      36ma836323493      2020-04-17 13:52:49 +08:00 想想问题的根本原因,然后再去进行考虑,想不到问面试官,然后再考虑能给解决方案不 | 
|      38ElicaKing      2020-04-17 14:12:40 +08:00 分页加懒加载不好吗,用到哪加载哪部分。 | 
|  |      39encro      2020-04-17 14:20:57 +08:00 报表, 要速度, 不就是加一个缓存表嘛? | 
|  |      40aalikes95      2020-04-17 14:25:01 +08:00 学习了,原来是这样子 | 
|  |      41tabris17      2020-04-17 14:26:04 +08:00 预生成 reporting table | 
|  |      42Joyboo      2020-04-17 14:29:17 +08:00 才千万级,能有多慢?索引完全够用 | 
|  |      43crc8      2020-04-17 14:54:35 +08:00 你应该这样回:不要问,问就是堆硬件。 | 
|  |      44rrfeng      2020-04-17 15:22:31 +08:00 不知道方向的话你可以问现在是怎么实现的呢?有了当前实现你才能给出优化建议。 如果他也不告诉你,那你就把你自己认为最好的方案写出来就行了啊,或者你先写一个简单方案,然后逐步优化它,体现你的思路。 | 
|  |      46F281M6Dh8DXpD1g2      2020-04-17 15:33:59 +08:00  1 千万级分页展示? 别理他直接走 没哪家公司是这样看数据的 | 
|      47Tezos      2020-04-17 16:12:41 +08:00 直接告诉他 充钱世界可及 | 
|      48Johnny168      2020-04-17 16:13:09 +08:00 S 不行,上 O | 
|  |      49aec4d      2020-04-17 16:14:42 +08:00 via iPhone 思维被限制在了关系型数据库的死胡同里.... | 
|  |      50ArtIsPatrick      2020-04-17 16:20:21 +08:00 via iPhone 伪需求,不可能需要一下查这么多 | 
|  |      51asLw0P981N0M0TCC      2020-04-17 16:22:13 +08:00 可能你喝水不多吧 像你头像一样多喝点水 | 
|  |      52zhouyou457      2020-04-17 16:23:43 +08:00 现在就在做类似的需求... 流水数据分页查询,物理机顶配刀片,全固态盘,数据库 mysql,单表 3 亿+数据,有交易时间分区,复合主键,没有自增 id(别问我为什么没有自增 id,我也很想问当初的设计者) 在多次优化 sql 无果后,果断停机拆表加自增 id... | 
|  |      53nonea      2020-04-17 16:28:38 +08:00 你跟他说 Doris 啊 | 
|      54alienx717      2020-04-17 16:29:26 +08:00 千万级分页展示,看着像什么东西的日志,流式数据之类的 | 
|  |      55ifconfig      2020-04-17 16:36:27 +08:00 简单方式:分区 复杂方式: 1 、分表 2 、通过 mycat 做中间层 不就完事了 贵族方式: 另外,阿里云出了个 DRDS (很贵),只要有钱,能有啥性能问题 --------------------------------------------------- 另外,加了索引不一定命中了索引,命中了索引不一定会快,要留意 explain 的 type 和 extra,如果出现 using filesort 和 using temporary 照样得跪,这个时候都会反问面试官,加了索引一定命中吗,命中了效率一定快吗? | 
|      56Easzz      2020-04-17 16:37:37 +08:00 扩字段、适当冗余、减少连表、优化索引。年度报表可以每月汇总,避免一次性查一年,减少数据的聚合。 | 
|      57CRVV      2020-04-17 16:43:02 +08:00 如果面试的问题就是太慢要怎么解决,那这个问题没什么意义,就跟问多么多么大的并发要怎么实现一样。 这种问题通常就是堆点什么名词,或者面试官也是在论坛博客随便看了点讨论拿来问的。 如果真要认真地问这个问题, 首先当前是怎么实现的,具体是个什么查询,慢是有多慢,预期要达到多快的速度,对数据的实时性要求有多高,这个报表有多高的查询频率,开发这个报表愿意付多少成本,运维这个报表愿意付多少成本。 这些都得先说清楚,根据不同的情况显然可以给出很多种不同的方案。 | 
|      58ccoming      2020-04-17 16:52:23 +08:00 看看阿里云的 DataV 数据可视化?   双 11 销售大屏都使用这个的 | 
|  |      59xcstream      2020-04-17 16:52:39 +08:00 才千万啊 直接查 | 
|  |      61Airon      2020-04-17 17:37:51 +08:00 或者面试官只是想看看你解决问题的思路。 | 
|      62cs419      2020-04-17 17:46:01 +08:00  4 这类开放性的问题 回答的时候,需要自己加上限制条件不然没法答 你如果有相关经验,就把当时的场景方案讲一下 通常这类问题的解决方案都是折中的 比如上亿的数据 模糊搜索 那显然用 es 比 mysql 好 (不需要事务) 比如加载到特大内存,快速查询 (特有钱) 比如预先计算, 缓存预热 比如分表分库 具体问题具体分析 有相关经验还能问问是不是 xx 导致的,没经验只能干瞪眼 有些提问就纯属抬杠, 分库分表他说慢 说分布式集群 他说有可能全挂掉 异地多活 他都能说网线断了 你这问题就提供了两个点 慢 年度数据报表 报表一般来说 可以先算好的 慢 到底是慢在哪里 就是找痛点 找瓶颈 | 
|      63crazyneo      2020-04-17 17:47:19 +08:00  3 实际上这个问题是想问你怎么做数据库优化,只不过千万级单表的数据有点太 low 了…… 一般来说有 3-4 层优化的空间,sql 语句与索引,表结构分析与视图建立,物理硬件与系统配置。 sql 语句与索引这点应该绝大多数人都会想到,常见分析工具是 explain/show processlist/slowlog/show session status 等等,一般优化思路包括执行计划优化 /索引建立 /长事务分析与优先级调整等等。 表结构分析与视图建立,如是否满足自增主键,能否提前建立物理视图来满足分页展示需求。 物理硬件与配置方面,更新硬件配置,建立连接池,是否要增加 swap,是否要调整引擎层刷盘策略,数据库配置参数如 mysql 中 innodb 的 buffer pool 配置 /查询缓存,或者 rocksdb 的 compact 策略等等。 如果放到更高一点层面来说,一般还会有下面几点。 1. 分布式 /分库分表与数据归总。 2. 缓存。 3. OLTP 与 OLAP 差异,列存数据库与行存选择。 | 
|      64LICOEVE      2020-04-17 17:48:37 +08:00 考的就是分析问题的能力。。。 | 
|  |      65skaly      2020-04-17 17:49:33 +08:00 先搞清楚是返回数据慢,还是前端渲染慢啊? | 
|      66hsuvee      2020-04-17 17:50:28 +08:00 1. 有序 id 分页 select * from aaa where id > 1000000 limit 100 2. 分表 3. es | 
|  |      67skaly      2020-04-17 17:51:00 +08:00 返回数据慢 上面各位老哥已经说的差不多了 前端渲染慢 的话可以充钱换硬件了 | 
|      68louis2003      2020-04-17 18:06:32 +08:00 这个题目应该是数据大(一千万数据还好吧)分页的问题? 一般分页的话,就算是走索引数据量也是太大了,还是线性查找,然后再跳过过滤 mysql 的机制是这样的。 所以有很多直接基于 id 搜索先过滤再做分页的处理。 | 
|      69gemini767      2020-04-17 18:16:58 +08:00 olap 离线统计 | 
|  |      70drydiy      2020-04-17 18:19:30 +08:00 楼主你用鸟习惯要改改啊。 | 
|  |      71zhangsimon      2020-04-17 18:38:17 +08:00 我不会编程… 但看你题目描述我脑子里直接蹦出两个字“缓存” | 
|  |      72zuoakang      2020-04-17 18:38:28 +08:00 via Android redis 集群加 pika | 
|  |      73ironMan1995      2020-04-17 18:39:55 +08:00 via Android 我前端,我想能不能将数据根据某种规则或者类型分类存在不同数据库或者什么东西中。然后同时查不同数据库然后聚合,这样会不会快一点 | 
|  |      74jswh      2020-04-17 18:48:51 +08:00 优化 sql,添加索引,冷热分离,添加缓存,分库分表,更换架构,数据库性能优化常规思路 最后一步:怼产品经理(这个功能实现不了)(手动狗头 | 
|  |      75BigR      2020-04-17 19:12:26 +08:00 @angryfish 正常的结果难道不是,一步步和面试官探讨,说出具体细节,解决这个问题,然后你就不用来上班了么。问题都解决了,你还来干嘛。 | 
|      760x11901      2020-04-17 19:16:18 +08:00 我以为最后一问是:“你还有什么想要问我的?” | 
|  |      77visitant      2020-04-17 19:21:39 +08:00 既然是报表,预生成一下? | 
|  |      79piao5109      2020-04-17 23:55:24 +08:00 via iPhone 开放式的问题 1 、硬件配置 2 、数据建模的时候 根据查询需求特点做优化 3 、合适的索引 4 、查询语句优化 5 、加缓存 6 、分表、分库、读写分离等 | 
|      80laminux29      2020-04-18 00:33:32 +08:00  3 这个问题的本质,其实是面试信息不对称的羞辱,而不是解决优化问题。 千万级数据,是个很有意思的数据量。往小的说,64 位 ID+64 位数据再加一个简单索引,撑死就几百 M 的非关系型内存数据。如果设计成流式统计或固定数组 + 矢量更改表,以内存高达 G 级与每秒海量 IOPS 的处理速度,查询与分页时间能在 ms 级完成。但如果往大的说,把满载撑死的单行平均数据,非顺序的链式(乱跳)结构,各种强关系的牵扯,各种触发器的拖累,加上数据存储在每秒 iops 低于 1k 的低速机械硬盘里,以及单次查询限定了非常小的内存空间,那么一次查询的排序 + 处理,能耗上两三小时也说不定。 这种情况下,面试官说不定早就针对他们自己的情况,给出了优化程度相当高的方案,然后在不告诉你完全信息的情况下,让你猜他们的场景与算法。他这种行为,面试很有可能已经不是他的唯一目的,说不定是他在同事面前故意刁难面试者,来哄抬他自身的技术价格。如果被面试者的级别越高,他就能越得逞。此时,就算你中了大奖,完整地猜出他们的场景,并给出了优于他的方案,说不定他也会一口否决你,然后说你的方法不行。 避免这种非对称羞辱的最佳方法,是你在面试前,针对他们产品的某种特性,给出更好的解决方案,并且提前做出性能对比测试并得出报表。此时,你完全可以不回答这个问题,然后直接扔出你的报表,说要不录用,要不你换公司,甚至换到竞品公司。当然,如果面试时,面试官很厚道,你可以保留这个行为。 | 
|  |      81version      2020-04-18 00:35:42 +08:00 via iPhone 一般报表涉及都是运算统计排序为主, 这种数据量大的, 统计结果时效性是保证不了的,都是离线统计导出的 因为他提到了了分页慢,就知道用了大量的 order by 和分页,命中索引只能优化前面的几十万的数据,当分页去到第 200 万行,后面性能就很低了, 简单合理便宜处理办法就是根据需要计算的字段,自定义计算,丢内存运算,然后导出来,不够再加磁盘,所以数据结构就很重要了 | 
|  |      82levelworm      2020-04-18 02:43:46 +08:00 via Android 年度的一年才做一次吧,没有 dwh 之类的吗 | 
|  |      83MintZX      2020-04-18 04:40:00 +08:00 @huntcool001 对,这也是我想说的。 我做过 20 亿条单个表的数据库。其实以主键排序 20 亿并不会慢。而索引的问题在于,如果加索引的列有大量重复的值的时候,索引是无效的。所以一般索引只对主键,或者时间戳比较有效。这个时候要么分表,要么上 elasticsearch 。都是挺好的解决办法。 | 
|  |      84msg7086      2020-04-18 05:22:31 +08:00 via Android  4 @laminux29 这个问题的本质难道不是考察你问诊的能力? 面试官问了一个模糊场景的问题,作为程序员难道不是去尝试缩小问题点,找到具体问题在哪,然后再针对优化? 让你猜场景和算法?难道不是让你问他场景和算法然后去缩小问题? 就说经典的面试问题,如果用户输入了你的网站地址,按下回车,但是网站迟迟不加载,问题在哪。你不去一步一步分析场景缩小范围找到问题点,坐在那里傻瞪着面试官,那人家不拒你留着过年么。 | 
|      85shiyouming91      2020-04-18 05:57:33 +08:00 via iPhone 年度数据报表?我觉得可以问一下是不是实时更新的,不是的话可以考虑预渲染? | 
|  |      87aladdindingding      2020-04-18 08:52:23 +08:00 clickhouse 列存数据库了解一下 | 
|      88YFeei      2020-04-18 08:58:19 +08:00 via Android select  字段 from 表 where id in ( select id from 表 limit  x x )网上好像搜到过这种答案…… | 
|  |      89Fleey      2020-04-18 09:20:39 +08:00 多数人都回答错了。。。 面试官想要你说的是“使用 nosql 分组缓存统计” | 
|  |      90didala      2020-04-18 09:22:47 +08:00 | 
|  |      92acrisliu      2020-04-18 09:24:35 +08:00 via Android 数据量大分页不要用 limit offset,用 keyset 分页。 | 
|  |      93msg7086      2020-04-18 09:50:20 +08:00 @laminux29 我并没有否认不平等关系。但是不平等关系和羞辱和否决和否定都没有决定性的联系。 考察的目的是找出那些人符合面试官认为的适合公司的候选人,筛掉你当然是因为你不符合面试官心目中的候选人形象。 | 
|  |      94murmur      2020-04-18 09:51:24 +08:00 年度数据报表肯定是要缓存的,一年就出一次的东西,实时计算何必呢,设定个计划任务,一月的某一个半夜算他几个小时,整个一年都有的看 | 
|  |      95winglight2016      2020-04-18 10:06:46 +08:00 这种具体的项目问题,并不是封闭式问题,没有什么标准答案。一般来说,你能给出越多的可行性提升性能方法,表现越好。当然,也可以从整个业务流的优化说起,也就是从浏览器到 web server,再到缓存,业务模块,数据库这些环节,每一个地方都有可优化的方法。最后,如果是优化 SQL,可以使用执行计划考察一下 SQL 慢在哪里。 | 
|      96daozhihun      2020-04-18 10:19:19 +08:00 emmm 。。。。楼上有些说千万级数据没有浏览需求的,我只能说我之前做过的一个系统还真有。。。 流水报表,一张表上亿都有,当然不可能是一页展示完,支持各种条件分页查询。 | 
|      97nortonlai      2020-04-18 10:22:54 +08:00 via Android 加索引这种回答不应该是无工作经验的面试回答吗?工作经验大于一年敢回答这么简单果断是不能要的 | 
|      98deep89381      2020-04-18 10:59:10 +08:00 ’加索引’这个回答太初级啦。如果自己真的经验很丰富,可以说出很多来。 比如用 limit o, n 分页, 随着分页越来越大,速度会越来越慢,怎么优化呢? 根据查询条件,如何做索引优化呢 ? 千万级数据量可以分库分表; 数据库选型用 mysql, pg,mongo, greenplum.. .. . . . 随便 bala 可以说半个小时了 | 
|  |      99nockyQ OP @nortonlai  @zhuifeng1017 可能确实是我表达不当,“加索引”不是我回答的全部。我想表达的意思是,我提出的“加索引”、“分库分表”这些解决方向没有像预期的那样得到正向反馈。 确实也是经验不够导致的吧。当时的状态过于被动,说完自己想法之后就在等面试官能给点提示。如果能沉住气去追问然后再给出别的解决方案应该会得到更好的结果。 | 
|  |      100encro      2020-04-18 11:25:19 +08:00 @zhouyou457  这就是日志型数据库的事情了。 |