十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SQL面试高频考点全解析:窗口函数、索引优化与安全防护

SQL面试高频考点全解析:窗口函数、索引优化与安全防护 刚刷完一个周期的SQL面试题把能想到的考点都整理了一遍。SQL这个东西在技术面试里极其特殊它不算一门“语言”但几乎每个后端、测试、数据岗位都会考。尤其牛客讨论区里的面经出题风格非常贴近实际工作基础语法、窗口函数、索引优化、慢SQL排查、MyBatis动态SQL、SQL注入防护几乎覆盖了日常开发会碰到的所有场景。这份笔记适合三类人一是准备校招和跳槽的开发者面经里SQL题目虽然不算难但答得完整、有层次感能给面试官留下明显的好印象二是工作中每天都在写SQL但从来没系统整理过的人很多细节属于“用过但说不出所以然”面试最容易在这里翻车三是有一定经验、想借机补齐性能优化和安全意识的工程师。下面按我自己的复习路径把高频考点一条一条拆开讲清楚。1. 先从面试官视角拆解SQL考点1.1 为什么面试官总爱考SQL而不是直接问项目我在准备阶段发现一个规律面试官问SQL题重点往往不是“你能不能写出来”而是“你在写的时候有没有自己的想法”。项目经历可以包装但SQL题是一道带标准答案的思维题一问就知道你平时是顺手写业务代码还是真的琢磨过数据是怎么被查出来的。举个例子面试官问“LEFT JOIN和INNER JOIN有什么区别”初级回答是“一个返回左表所有行一个只返回匹配行”这个答案只能及格。如果补一句“在数据量大的时候LEFT JOIN会让驱动表全表扫描的风险更高很多慢SQL都是因为滥用LEFT JOIN导致驱动表选错”面试官就会觉得你踩过坑。八股题其实考的就是这个“踩坑后沉淀下来的理解”。SQL考点还有一个特点就是范围可控。翻来覆去就那几大类查询语法、连接逻辑、聚合分组、窗口函数、索引机制、执行计划、优化手段、注入防护、框架集成。把这几块梳理成一张知识地图复习效率比漫无目的刷题高很多。1.2 一张可操作的SQL知识地图我自己整理考点时不是按“初级、中级、高级”分的而是按“面试提问频率”和“实际工作中踩坑率”两个维度排了优先级第一梯队多表连接、聚合与分组、去重、子查询、窗口函数。这一部分占比最大几乎每场面试都会出1到2道手写题。第二梯队索引原理、EXPLAIN执行计划、慢SQL优化思路、分页查询优化。这部分属于“聊出来的题”面试官先让你写一条SQL再追问“数据量大怎么办”。第三梯队SQL注入与防护、MyBatis动态SQL、事务隔离级别、数据库权限管理。这部分通常和项目结合着问比如“你们项目里为什么要用${}有没有风险”。第四梯队不同数据库的差异比如MySQL、PostgreSQL、SQL Server的语法区别工作流引擎里能不能写SQLFlowable就有SQL任务节点JDBC连接池超时设置等。这些属于锦上添花答出来会显得知识面很广。按这个地图复习基本能把面试中八成以上的SQL问题覆盖住。下面每个梯队展开细说。2. 基础SQL考点送分题也不能掉链子2.1 聚合查询与去重最容易出错的细节聚合查询是SQL手写题里最基础的考点但也是挂科率很高的题。问题往往不出在SUM、COUNT、AVG这些函数本身而是出在GROUP BY和WHERE、HAVING的配合上。老生常谈的一个坑WHERE是在分组之前过滤HAVING是在分组之后过滤。面试题经常改成这样查每个部门工资大于5000的员工人数很多人会把5000的过滤条件写在WHERE里结果把工资低的员工过滤掉之后人数统计就失真了。实际上应该先用WHERE把“员工级”条件过滤掉再用HAVING对“部门级”聚合结果过滤。判断标准很简单条件里带聚合函数就必须用HAVING条件只是普通字段用WHERE。去重是另一个容易踩坑的点。DISTINCT是对整个查询列组合去重不是只对某一列去重。SELECT DISTINCT user_id, user_name会保留user_id和user_name都相同的行如果同一个人改过名就会查出两条记录。面试里手写“统计活跃用户数”时正确写法是SELECT COUNT(DISTINCT user_id)如果误写成SELECT COUNT(DISTINCT user_id, user_name)结果就错了。还有一个实用细节用GROUP BY去重时查询列必须都在GROUP BY中出现否则SQL Server和MySQL的ONLY_FULL_GROUP_BY模式都会直接报错。这也是面试官喜欢追问的“为什么我的SQL报错”类问题。2.2 多表连接的执行顺序与优化思路连接问题几乎场场必考。面试官常用的问法是给两张表一张用户表、一张订单表写SQL查出每个用户的订单数。很多人第一反应就是LEFT JOIN因为“用户可能没有订单也要查出来”。这个方向没错但不完整。更好的回答要分三步。第一步说明连接类型怎么选INNER JOIN只要两边匹配的行LEFT JOIN保留左表全部行RIGHT JOIN保留右表全部行FULL JOIN两边都保留。第二步结合业务场景判断用户表作为主表时用LEFT JOIN是合理的。第三步补一句关键优化LEFT JOIN之后再按用户ID分组实际上会把用户表和订单表先做笛卡尔积式的匹配再压缩行数如果用户表和订单表都很大这个操作代价不低。可以优化成先对订单表按user_id做GROUP BY得到每个用户的订单数后再和用户表LEFT JOIN。这种“先缩小数据范围再连接”的思路比单纯给出SQL让面试官眼前一亮。连接时还有一个高频追问“连接条件字段有没有索引”如果订单表的user_id没有索引连接过程就是嵌套循环全表扫描数据量到百万级就会明显变慢。后面讲索引时会专门说这个问题。另外多表连接时要注意字段歧义问题。两张表都有id字段时必须在SQL里写清楚表名或别名比如u.id和o.id。我自己加餐练习时由于字段没加别名导致SQL执行报错“column reference is ambiguous”这种低级错误在面试手写时特别影响印象分。2.3 子查询与临时表/CTE的取舍子查询是解决复杂查询的利器但用不好就是性能杀手。最常见的场景查每个部门工资最高的员工这几乎是一道必考题。解法有两种一种是子查询先找出每个部门的最高工资再和原表关联另一种是用窗口函数ROW_NUMBER()这个留在第三节细说。很多人在关联子查询这里犯迷糊。关联子查询的特点是内层查询引用了外层查询的表字段执行逻辑是“外层每取一行内层就执行一次”。这种写法在数据量小时没问题数据量一大就会慢得离谱。面试官问“子查询性能差怎么办”时可以回答改写成JOIN或者把子查询结果先存入临时表/公共表表达式CTE。CTE在可读性上比嵌套子查询好太多尤其是多层嵌套时用WITH开头的CTE能把逻辑一层层拆出来后续维护也方便。这里还要提一个实操点不同数据库对临时表和CTE的支持有差异。MySQL 8.0开始支持CTE之前的版本只能用临时表SQL Server和PostgreSQL对CTE支持一直很完善Oracle的写法又稍有不同。面试时说清楚“当前项目用的什么版本、这个语法在这个版本里是否可用”比背语法更能体现实战经验。3. 高级查询与窗口函数拉分题的突破口3.1 row_number、rank、dense_rank的区别与使用场景窗口函数是SQL面试的拉分题会的人一波带走不会的人现场编半天。三个排名函数是最高频考点我见过无数人把rank和dense_rank搞混。假设一个班成绩如下A 100分B 100分C 90分D 80分。ROW_NUMBER() OVER (ORDER BY score DESC)直接给行号不管分数是否相同结果是1、2、3、4。RANK() OVER (ORDER BY score DESC)分数相同就并列但下一个排名会跳过结果是1、1、3、4。DENSE_RANK() OVER (ORDER BY score DESC)分数相同并列下一个排名不跳过结果是1、1、2、3。面试手写题“查每个部门工资排名前3的员工”用DENSE_RANK是标准答案因为并列第1时不希望第3名消失。如果需求只是“给每行编个号”比如分页场景用ROW_NUMBER更合适。把这个区别讲清楚再把PARTITION BY加进去按部门分组就基本能编出标准答案了。窗口函数的执行顺序值得多说一句它是在WHERE、GROUP BY之后执行的。所以如果你在WHERE里想着“过滤掉排名大于2的记录”这是行不通的必须把窗口函数的结果包一层子查询再在外面过滤。这是我和身边同事都踩过的一个坑。3.2 lag/lead与case when组合实战进阶考点里LAG和LEAD出现频率也很高。这两个函数用于取同一分区内前后行的数据典型场景是“计算环比增长”或者“找出连续登录天数”。计算环比增长的写法大概是SELECT month, amount, amount - LAG(amount, 1) OVER (ORDER BY month) AS diff FROM sales;LAG(amount, 1)的意思是取上一行的amount值偏移1行。如果遇到第一行没有上一行返回NULL通常外面再套一层COALESCE处理。“连续登录天数”是面试高频题做法是给每个用户按日期排序生成ROW_NUMBER再用登录日期减去行号如果日期连续这个差值就是同一个日期。然后把用户和差值一起GROUP BY统计每组数量。这套解法把窗口函数、日期函数、聚合函数全串起来了面试官最喜欢这种综合题。CASE WHEN也是常客常用来做“行转列”。比如把“用户行为表”的多个行为类型转成多列每个人一行每列对应该用户某行为的次数就可以用SUM(CASE WHEN action_type click THEN 1 ELSE 0 END)这种写。MySQL 8.0以后可以用FILTER语法但CASE WHEN的写法跨数据库兼容性最好面试时也更通用。3.3 常用函数与空值处理技巧函数题容易被轻视但“空值处理”几乎人手一道。新手最容易犯的错误是用等号判断NULL。实际上任何与NULL的比较运算返回值都是NULL不是TRUE也不是FALSE。正确判断是IS NULL或IS NOT NULL。面试中还有一个高频坑“COUNT()和COUNT(column)有什么区别”。COUNT()统计行数COUNT(column)只统计该列非NULL的行数。如果某列大量为NULL两个结果会差出不少。业务代码里如果没注意统计人数就会悄悄变少。空值排序也经常被问ORDER BY默认把NULL排在最前面还是最后面不同数据库不一样。MySQL里NULL默认排最前Oracle里NULL默认排最后。想要统一结果就得显式写NULLS FIRST或NULLS LAST但MySQL 8.0之前不支持这个语法得用CASE WHEN拼ORDER BY这是一个很经典的跨数据库兼容问题。说到函数很多人都会查“SQL函数用法大全”这类资料但我的建议是重点掌握几类即可字符串函数CONCAT、SUBSTRING、REPLACE、日期函数DATE_FORMAT、DATE_ADD、DATEDIFF、条件函数IF、COALESCE、NULLIF、聚合函数COUNT、SUM、AVG、MAX、MIN。面试不会考冷门函数但一定会把几个常用函数组合在一道题里考。4. 索引与慢SQL优化八股里的硬核部分4.1 索引为什么快B树与回表索引是SQL面试里拉开差距的重头戏。面试官几乎一定会问“为什么加了索引查询就变快”很多人回答“因为不用全表扫描”这等于没说。要拆到数据结构层面才算是有效答案。索引底层的数据结构是B树。B树的特点是所有数据都存在叶子节点叶子节点之间用指针相连形成有序链表。这个结构的好处是首先树的层级矮一般三到四层就能存千万级数据查找次数等于树的层数不会随着数据量暴增而线性增长其次叶子节点有序适合范围查询查出一个区间可以顺着链表顺序往下扫。面试官还会继续追“什么是回表”。如果查询的字段全部在索引列里直接用索引就够这叫覆盖索引不需要回表。如果查询的字段不在索引里就要根据索引叶子节点记录的主键ID再到主键索引的B树里查一次完整数据这个过程叫回表。回答到这里可以补一句“为了避免回表很多场景会用联合索引和覆盖索引来优化查询”这就是加分项。索引失效是另一个高频考点。常见失效场景包括对索引列使用函数或运算使用LIKE时通配符在最前面使用OR且其中一个条件列无索引隐式类型转换导致匹配不上。这些我不仅背下来了还自己建表测试过因为面试官可能会反问“为什么对这个列套一层函数索引就失效了”原理是函数改变了列的原始值B树没法按原顺序查找。4.2 explain执行计划阅读方法知道索引原理还不够还要会看执行计划。面试时如果面试官给出一条慢SQL问“怎么排查”第一反应应该是EXPLAIN。EXPLAIN最关键的是多看几个字段type访问类型从好到差一般是const、eq_ref、ref、range、index、ALL。如果看到ALL意味着全表扫描基本就是慢SQL的信号。key实际选中的索引如果为NULL说明没用到索引。rows预估扫描的行数这个数字越大查询越可能慢。Extra常见有Using index覆盖索引、Using where在存储引擎层过滤、Using temporary用了临时表、Using filesort文件排序。出现Using temporary或Using filesort时通常意味着排序或分组没有利用到索引需要优化。举个例子我优化过一条分页查询原来的SQL是SELECT * FROM orders ORDER BY create_time LIMIT 100000, 20;MySQL里LIMIT的偏移量越大扫描的数据越多因为它会先把前100000行查出来丢掉再取第100001到100020行。EXPLAIN显示rows是100020大部分时间浪费在扫描无用行上。优化方案是用延迟关联或记住上一页最大ID比如SELECT * FROM orders WHERE id 100000 ORDER BY id LIMIT 20;这种“用上次位置代替偏移量”的思路是面试加分点。SQL Server 2012以上可以用OFFSET FETCH语法MySQL 8.0也有类似能力但ID分页永远是最快的方式前提是主键连续或近似连续。4.3 慢SQL优化常规处理流程与并行SQL优化慢SQL优化是仅次于索引原理的第二大问答题。面试官一般不指望你给出万能药而是看你有没有排查思路。我把过程总结成一个四步流程第一步先看是不是真的慢。结合业务场景判断执行时间是否合理有时候一条SQL跑1秒其实可以接受如果业务要求毫秒级响应那就要查。这一步可以通过数据库慢查询日志、Druid监控面板或DBeaver的查询日志来确认。第二步EXPLAIN看执行计划定位是全表扫描、没走索引、临时表还是文件排序。这一步能排除掉大部分问题。第三步看SQL写法。有没有不必要的子查询能不能拆成两条SQL能不能把OR改成UNION能不能把SELECT *改成只查需要的列很多时候问题出在“一把梭”的写法上。第四步看索引设计。单列索引能不能改成联合索引排序字段有没有覆盖到索引这里有一条经验联合索引要符合最左前缀原则查询条件里必须包含联合索引最左边的列否则索引不生效。“并行SQL优化”这个词我是在一个项目里真正接触到的。早期的MySQL、PostgreSQL单条SQL都是单线程执行后来像MySQL 8.0、PostgreSQL 11都支持了并行扫描SQL Server也有并行执行计划。面试时如果被问到可以从两个角度回答一是数据库层面的并行度配置比如MySQL的innodb_parallel_read_threads二是业务层面的并行方案把一个大数据量查询按时间范围拆成多个子查询多个线程同时执行再合并结果。后者面试官更爱听因为它体现了工程思维。顺带提一句数据库版本问题。很多人面试前临时下载SQL Server 2008 R2或2012来练手但面试官提到SQL Server 2022里的新功能时完全没概念。不同数据库版本的查询优化器行为差异很大比如SQL Server 2019开始支持了行模式内存OLTP和智能查询处理MySQL 8.0的优化器也比5.7版本强不少。面试时如实说“我项目里用的版本是哪个”比含糊其辞要好。4.4 JDBC连接池超时与“SQL执行10秒自动关闭”问题还有一个被讨论得很多的问题“JVM或者Spring Boot会设置一个SQL执行10秒自动关闭吗”这个问题本身有一点迷惑性面试官想考的是你有没有区分清楚不同层面的超时配置。答案是可以的但不是JVM直接设置的而是通过连接池和JDBC驱动配置的。Spring Boot默认的HikariCP连接池有connectionTimeout参数控制从连接池获取连接的超时时间JDBC驱动有socketTimeout参数控制网络读写超时超过这个时间没读到数据就会抛异常MySQL还有一个wait_timeout和interactive_timeout控制服务端关闭空闲连接的时间。所以“SQL执行10秒自动关闭”并不是SQL执行到10秒就被杀掉而是可能因为获取连接超时、socket读超时、或数据库服务端关闭空闲连接最终表现为执行失败。排查时要看错误日志里报的是拿不到连接、网络超时还是等待锁超时。网上很多资料推荐把socketTimeout设置得比一条SQL最大执行时间大一些避免慢SQL还没跑完就被误杀。面试时能说到这个细节基本就是满分答案。5. 安全与框架注入防护和MyBatis动态SQL5.1 SQL注入原理与万能密码绕过实验SQL注入是安全方向的核心考点而且面试官通常会结合具体场景问。原理其实一句话就能说清用户输入的数据被当成SQL代码拼接执行了。我在自己的测试环境里搭过一个SQL注入靶场验证过“万能密码”注入的原理。假设登录查询是SELECT * FROM users WHERE username admin AND password 123456;如果输入的用户名是 OR 11密码随便填拼接后的SQL会变成SELECT * FROM users WHERE username OR 11 AND password xxx;由于11恒为真整个查询条件恒为真于是登录就绕过了。这就是网上流传的“万能密码”原理。但我必须强调只能在自建的靶场环境里练习绝对不能拿真实系统做测试这是底线。防御手段最核心的一条是参数化查询。Java里的PreparedStatement、MyBatis里的#{}、Python里的参数化查询本质都是把SQL结构和数据分离数据库先编译SQL结构再把数据当纯参数传入数据永远不会被识别成代码。这样就算输入里有一堆引号和关键字也只是普通字符串。5.2 MyBatis中#{}和${}的区别MyBatis是Java后端面试绕不开的话题动态SQL相关的八股里#{}和${}的区别几乎必问。简要说两个都是占位符但#{}生成的是PreparedStatement的占位符?会做预编译有SQL注入防护${}是字符串直接替换相当于把内容拼进SQL语句里有注入风险。那${}是不是完全不能用也不是。在需要动态指定表名、列名、ORDER BY排序字段时比如ORDER BY ${column}因为表名和列名不能作为占位符参数只能用${}拼进去。这种情况就需要在代码层面对传入值做白名单校验。面试时我能给出的完整答案是“能不用就不用如果非要用必须加白名单限制防止任意列排序被利用来探库表结构。”MyBatis还有一套动态SQL标签包括if、choose、when、otherwise、where、set、foreach。这段内容我用一个例子说批量插入用户通常会写insert idbatchInsert INSERT INTO user (name, age) VALUES foreach collectionlist itemitem separator, (#{item.name}, #{item.age}) /foreach /insert面试官会追问“批量插入时SQL会不会太长”MySQL的max_allowed_packet有限制一次插入1万条可能把消息包撑爆。解决方案是分批插入每次500条到1000条。这类问题平时不碰真不知道属于典型的“场景八股”。Flowable引擎能不能写SQL这个在业务开发中也遇到过。Flowable本身是工作流引擎但支持在流程节点里配置SQL任务用于查询或更新业务数据。这种“流程里嵌SQL”的场景要特别注意SQL注入和事务边界问题因为工作流引擎的执行环境和普通Service层不太一样事务传播行为容易踩坑。5.3 Druid防火墙报sql injection violation的处理阿里巴巴的Druid连接池自带一个SQL防火墙过滤器如果配置了wall过滤器它会拦截疑似注入的SQL。我遇到过真实报错java.sql.SQLException: sql injection violation, dbType oracle, druid-...这个报错在测试环境经常让人一脸懵因为有时候写的SQL明明没问题却被拦截了。常见原因有三类一是SQL里确实有类似注入的特征比如恒真条件、注释符号二是Druid的防火墙规则误判例如某些数据库特定语法它不认识三是在Oracle的dbType下Druid对某些写法支持比较严格。排查步骤通常是先看被拦截SQL的完整内容判断是否真的存在注释符、OR 11这类东西如果不是可以在启动参数里暂时关闭wall过滤器定位问题或者针对配置调整wall的allow语句。不过线上环境关闭wall前要慎重它是安全兜底。面试时能讲出这个真实报错比背“Druid是连接池”要加分得多。5.4 数据库权限与隐藏用户数据库权限管理也出现在一些面经里比如“如何对用户隐藏数据库”。大多数数据库都支持细粒度权限配置。MySQL里可以REVOKE掉某个用户对information_schema之外库表的权限甚至限制只能访问指定库。SQL Server里有架构Schema和数据库用户体系可以给用户只分配public角色加特定表的SELECT权限。这里的核心不是背权限命令而是理解“最小权限原则”。面试官可能会问“为什么订单表不能让所有开发都有DELETE权限”不只是安全问题还有数据完整性风险。一个手滑的DELETE没加WHERE如果没有权限保护整表数据就没了。所以很多公司会区分读写账号和只读账号日常排查问题用只读账号变更数据用专门的流程。这个思路回答“隐藏数据库”问题时会显得更立体。6. 面试实战复盘与备考建议6.1 几道经典面试真题复盘我在牛客面经区挑选了几道出现频率最高的SQL题简单复盘一下解题思路。第一题“用一条SQL查出每门课程成绩第二高的学生”。经典解法是用窗口函数ROW_NUMBER() OVER (PARTITION BY course_id ORDER BY score DESC) 2。如果课程成绩可能并列需要用DENSE_RANK。答完窗口函数版本后可以补一句“如果数据库版本不支持窗口函数可以用自连接子查询实现”展示兼容性思维。第二题“统计连续登录3天以上的用户”。先把登录日期按用户去重再用DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY)生成分组字段然后分组统计。这道题的思路比答案更重要面试官想知道你能不能想到“用日期减行号”这个技巧。第三题“对比两个表的差异”。解法不止一种可以用NOT EXISTS、LEFT JOIN加IS NULL、EXCEPT/MINUS取决于数据库。面试官会追问每种写法的性能这时候提到“小表驱动大表”“连接字段要有索引”就不错。第四题“慢SQL有哪几种典型情况”。这种开放式问题适合用“案例原因方案”的结构回答我一般讲三个真实案例索引失效、大偏移量分页、WHERE条件里对索引列做函数运算。6.2 刷题与复习路线推荐冲刺阶段我的复习顺序是这样的第一步基础语法快速过一遍重点看JOIN和GROUP BY。这一步不用花太多时间可以考虑拿《SQL必知必会》这本书当墙脚一天翻完前十二章。第二步集中刷窗口函数题。这部分的执念是“不背题把套路吃透”。牛客上的SQL题库、LeetCode数据库题都可以按窗口函数标签筛选来做。第三步储备优化和排查知识。重点看EXPLAIN的每个字段含义、慢SQL排查流程。我会在本地建一个百万行数据的测试表随意写几条慢SQL看执行计划到底长什么样。第四步准备工具链和常见操作。DBeaver导入SQL文件、执行SQL、查看执行计划都很方便我平时都用它。代码格式化可以用SQL格式化工具面试手写时虽然不能依赖工具但平时写得整齐对思路整理有帮助。数据库相关的工作流比如SQL Server自动备份、修改数据前的SELECT转UPDATE确认也要心里有数。6.3 环境反复验证是理解的唯一路径很多知识点光靠背面试时一紧张就会卡壳。比如事务隔离级别、脏读、不可重复读、幻读这些概念看十遍不如自己开两个命令行窗口验证一遍。我的验证方法是本地装一个MySQL开两个终端一个终端开启事务但未提交另一个终端去查同一条记录观察在不同隔离级别下能不能看到数据。测完再回到面试题“RR级别下间隙锁解决幻读”理解整个机制的印象会深很多。SQL Server 2019在Windows上安装比较方便适合练习SQL Server特有的语法比如TOP和OUTPUT。MySQL练手用Docker拉个镜像也很快。环境老一点没关系初学阶段用SQL Server 2008 R2或2012 Express也完全够用重点是语法和逻辑不能错。6.4 关于“背八股”这件事的一点个人看法现在技术社区对八股文有一定争议有人觉得背题没意义。我的观点是SQL这道八股跟那些靠死记硬背的人文类问题不一样它在实际工作中真的会用到。你说你懂LEFT JOIN但真让你优化一条关联查询时连EXPLAIN都不会看那跟没懂是一样的。所以我建议准备时多问自己一句“为什么”。为什么LEFT JOIN不一定比INNER JOIN慢为什么COUNT(*)在MySQL 8.0里不需要全表扫描为什么慢SQL日志里只记录超过阈值的查询一个个为什么追问下去八股题就变成了实战题。我个人在复习过程中最有价值的一件事是把一条报错的SQL拿到了本地真实表里反复测试直到彻底搞明白是索引失效还是查询逻辑错误。面试那天面试官问“你遇到过什么SQL问题”时我直接把这个真实案例讲了出来。他明显比听到背诵的答案更感兴趣。SQL面试的准备过程本质上就是把脑子里的经验重新整理一遍的过程。题库是别人的经验是自己的两者结合才算真正把这一题吃透。
返回列表