数据库面试问答
1、什么是索引?它有什么作用?
- 索引是数据库中一种特殊的数据结构(如B+树),用于快速定位数据。
- 作用:加速查询(WHERE、JOIN、ORDER BY)、强制唯一性(唯一索引)、优化聚合操作(GROUP BY)。
2、 为什么索引能提高查询速度?
索引通过有序数据结构(如B+树) 减少磁盘I/O次数。无需全表扫描,直接定位数据位置
3、 什么样的信息适合成为索引?什么样的信息不适合成为索引?
适合成为索引:
- 高频查询字段(WHERE、JOIN条件)
不适合成为索引:
- 低区分度字段(如性别、状态标志)
- 频繁修改的字段(索引维护成本高)
- 大文本字段(如TEXT/BLOB,建议用前缀索引或全文索引)
- 不参与查询的字段
4、为什么B+树更适合做存储索引?
- 磁盘I/O优化:叶子节点形成链表,适合范围查询和顺序扫描。
- 高扇出性:非叶子节点仅存键值,单页可存储更多指针,减少树高度。
- 数据全存于叶子:查询稳定性更好(时间复杂度恒为O(log n))。
5、密集索引与稀疏索引的区别?
密集索引 | 稀疏索引 |
每行数据都有索引项 | 仅部分数据有索引项(如按块索引) |
数据与索引绑定(如InnoDB主键) | 索引与数据分离(如MyISAM) |
查询更快但占用空间大 | 空间小但需二次查找 |
6、 如何定位慢SQL?
- 开启慢查询日志:slow_query_log = ON
- 分析日志工具:mysqldumpslow 或 pt-query-digest
- EXPLAIN诊断:查看执行计划(索引使用、扫描行数)。
7、如何优化MySQL查询性能?
- 索引优化:添加缺失索引,避免索引失效(如函数操作、类型转换)。
- SQL改写:减少子查询,用JOIN替代IN。
- 分库分表:数据量过大时水平拆分。
- 缓存:使用查询缓存或Redis。
8、什么是联合索引?
联合索引对多个列组合建立的索引(如 INDEX (col1, col2, col3)),可以加速多个列的联合查询。
9、索引是建的越多越好吗?
不是的,
- 优点:提高查询速度
- 缺点:性能上的开销,增删改操作变慢(需维护索引树)。占用额外磁盘/内存空间。优化器可能选错索引。
- 建议:按实际查询需求创建,一般单表不超过5个
10、联合索引的最左匹配原则和成因?
原则:索引按从左到右顺序匹配。查询需包含最左列,否则索引失效。
-- 有效:使用col1、col1+col2、col1+col2+col3 -- 失效:单独使用col2或col3
成因:索引按首列排序,再按第二列排序,依此类推(类似电话簿)
11、 InnoDB 与MyISAM两种存储引擎有什么区别?
特性 | InnoDB | MyISAM |
事务 | 支持ACID事务 | 不支持 |
锁粒度 | 行级锁 | 表级锁 |
外键 | 支持 | 不支持 |
崩溃恢复 | 支持(redo log) | 弱 |
全文索引 | MySQL 5.6+支持 | 支持 |
12、什么是事务?事务的四个特性是什么?
事务:一组原子性操作的逻辑单元,最为一个整体执行,要么全部成功,要么全部失败。
事务的四个特性是ACID:
- Atomicity(原子性):操作全部成功或全部失败。
- Consistency(一致性):数据状态符合约束。
- Isolation(隔离性):并发事务互不干扰。
- Durability(持久性):提交后数据永久保存
13、什么是死锁?如何避免死锁?
- 死锁:两个事务互相等待对方释放锁。
- 避免:
- 按固定顺序访问资源。
- 减小事务粒度。
- 设置超时(innodb_lock_wait_timeout)
14、MySQL的隔离级别有哪些?
级别 | 脏读 | 不可重复读 | 幻读 |
READ UNCOMMITTED | ✓ | ✓ | ✓ |
READ COMMITTED | ✗ | ✓ | ✓ |
REPEATABLE READ(默认) | ✗ | ✗ | InnoDB通过MVCC解决幻读 |
SERIALIZABLE | ✗ | ✗ | ✗ |
15、MySQL分区表是什么?为什么使用它?
分区表:将大表按规则(如范围、哈希)拆分为多个物理子表。
使用场景:
- 数据量极大(如亿级),提升查询效率。
- 历史数据冷热分离(按时间分区)。
16、 如何做MySQL数据库的备份与恢复?
- 备份:
- 逻辑备份:mysqldump -u root -p dbname > backup.sql
- 物理备份:复制数据文件(需停服务或使用工具如XtraBackup)
- 恢复:
- 恢复mysqldump 备份:mysql -u root -p dbname < backup.sql
- 恢复物理备份:将数据文件恢复到MYSQL数据目录
17、MySQL中的锁有哪些?
- 按粒度:表锁、行锁、间隙锁(Gap Lock)。
- 按模式:
- 共享锁(S):允许读,阻止写。
- 排他锁(X):阻止读写
18、什么是MySQL的复制(Replication)?如何实现主从复制?
复制:将主库数据同步到从库。
主从配置步骤:
1)主库开启二进制日志(log-bin)。
2)从库配置主库信息(CHANGE MASTER TO ...)。
3)从库启动复制(START SLAVE)。
19、如何优化MySQL的连接池?
- 参数调整:
- max_connections:增大最大连接数(避免“Too many connections”)。
- wait_timeout:关闭空闲连接释放资源。
- 使用连接池中间件:如HikariCP、Druid
20、如何在MySQL中实现分页?
-- 常规分页(大数据量时深分页性能差) SELECT * FROM table LIMIT 20 OFFSET 40; -- 跳过40行,取20行 -- 优化:基于游标分页(记录上一页最后ID) SELECT * FROM table WHERE id > 1000 LIMIT 20;
21、MySQL中的NULL是什么?如何判断NULL值?
NULL:表示“未知”或“不存在”(非空字符串/0)
判断:
SELECT * FROM table WHERE col IS NULL; -- 正确 SELECT * FROM table WHERE col = NULL; -- 错误!
22、Group By常用在哪里?
用途:按指定列分组,进行聚合计算(如统计、去重)。
示例:
-- 统计每个部门的员工数 SELECT department, COUNT(*) FROM employees GROUP BY department;
23、Where和Having的区别?
WHERE | HAVING |
过滤原始数据行 | 过滤分组后的结果 |
在GROUP BY之前执行 | 在GROUP BY之后执行 |
不可使用聚合函数(如SUM、COUNT) | 必须使用聚合函数或分组字段 |
24、SQL语句的执行顺序?
逻辑顺序如下:FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT
SELECT department, AVG(salary) AS avg_salary -- 步骤5:计算别名 FROM employees -- 步骤1:定位表 WHERE hire_date > '2020-01-01' -- 步骤2:过滤行 GROUP BY department -- 步骤3:分组 HAVING AVG(salary) > 10000 -- 步骤4:过滤组 ORDER BY avg_salary DESC -- 步骤7:排序(可用别名) LIMIT 5; -- 步骤8:分页
为什么顺序重要?
- 别名作用域:
- WHERE 中不能使用 SELECT 定义的别名(因 WHERE 先于 SELECT 执行)。
- ORDER BY 可使用别名(因它在 SELECT 之后执行)。
- 聚合过滤:
- WHERE 过滤单个行 → 在聚合前执行。
- HAVING 过滤分组 → 在聚合后执行。
- 性能优化:
- 尽早用 WHERE 减少处理的数据量(比 HAVING 高效)
整理面试过程中的测试问答,常看常新,多多学习!有些问题是从其他人那里转载而来,会在文章下面注明出处,希望大家多多支持~~,觉得满意的话就送一朵小花花,谢谢! 内容目录:https://www.nowcoder.com/discuss/779856598809264128?sourceSSR=users