- 内连接 inner join:只返回两张表匹配到的数据,交集。
- 左连接 left join:左表数据全部保留,右表匹配不到补 NULL。
- 右连接 right join:右表全部保留,日常开发几乎不用,可改左连接替代。
2、union 和 union all 区别?
union:去重、自动排序,性能差- `union all:不去重、不排序,性能高,业务优先使用
3、where、having、group by 执行顺序?
from → where → group by → 聚合函数 → having → order by → limit
- where:分组前过滤原始数据
- having:分组后过滤聚合结果
4、模糊查询 like % 优缺点?
%xx、%xx%:不走索引,全表扫描xx%:前缀匹配,可以走索引
5、count (*)、count (字段)、count (distinct) 区别
count(*):统计所有行数,包含 NULLcount(列名):统计该列非空数据count(distinct 字段):去重统计,常用统计用户数
6、怎么计算转化率、占比?
- 公式:
ROUND(符合条件数量 / 总数量,2) - 结合
case when筛选条件数量 - ROUND(SUM(CASE WHEN status=1 THEN 1 ELSE 0 END)/COUNT(*),2)
7、窗口函数和 group by 区别?
group by:多行合并成一行,丢失明细- 窗口函数:不合并行数,保留明细,每行附带统计 / 排名
- 核心:
over(partition by 分组 order by 排序)
8、row_number /rank/dense_rank 区别
row_number():连续序号 1,2,3,4(同分不同号)rank():跳跃排名 1,1,3,4(同分同号,跳过)dense_rank():密集排名 1,1,2,3(同分同号,连续)
9、lag、lead 作用?
lag(字段):取上一行数据(环比)lead(字段):取下一行数据
10、同库多表关联用什么?
优先 left join,保证主表数据不丢失。
11、同实例跨库怎么查?
select * from db1.user left join db2.order on user.id=order.user_id
12、不同类型数据库怎么跨库查询?
异构库(MySQL/Oracle/SQLServer):
- 实时查询:Oracle dblink、SQLServer 链接服务器
- 报表指标:数据同步到统一数仓再查询(主流方案)
- 代码层:分别查两个库,代码内关联
13、什么是索引?作用?
索引是数据库目录,加速查询,降低 IO;
缺点:占用存储空间、增删改变慢。
14、索引失效场景(必背)
like %开头模糊查询- 索引列使用函数、运算:
left()、date()、+ - - 隐式类型转换(字符串和数字对比)
- or 左右字段一个无索引
- 不符合最左前缀原则(联合索引)
15、联合索引最左前缀原则?
建立索引 (a,b,c)
- 有效:where a=? /where a=? and b=?
- 失效:where b=? 、where c=? 跳过左边字段
16、主键、唯一索引、普通索引区别
- 主键:非空 + 唯一,一张表只能一个
- 唯一索引:唯一允许为空,可多个
- 普通索引:只加速查询,无唯一性限制
17、事务四大特性 ACID
- A 原子性:要么全成功,要么全回滚
- C 一致性:数据前后合法
- I 隔离性:事务之间互不干扰
- D 持久性:提交后数据永久保存
18、MySQL 事务隔离级别(从低到高)
- 读未提交
- 读已提交(RC)
- 可重复读(RR,MySQL 默认)
- 串行化
19、脏读、不可重复读、幻读
- 脏读:读到未提交的数据
- 不可重复读:同一事务内,两次查同一数据结果不同
- 幻读:同一事务,范围查询,前后条数不一致
20、如何优化慢 SQL?
- 用
explain查看执行计划 - 合理加索引,避免索引失效
- 避免
select *,只查需要字段 - 大表禁止模糊查询
%xx% - 分页深翻页优化:limit 大页码优化
- 杜绝大量 in、or,改用 join
- 分组、聚合提前过滤数据
21、explain 关键字段有哪些?
type:访问类型,range/ref/eq_ref/system 越好,all 全表扫描最差key:实际用到的索引rows:扫描行数,越小越快
22、limit 100000,10 为什么慢?
需要先遍历前 10 万行再丢弃,优化:
用主键 / 索引定位起始位置
select * from t where id>100000 limit 10
23、查找重复数据
select name,count(*) from user group by name having count(*)>1
24、删除重复数据,保留一条
delete from user where id not in (select min(id) from user group by name)
25、分组后取每组最新一条
配合窗口函数 row_number 分组排序取第一行,面试高频。
