数据库面试问答

1、什么是索引?它有什么作用?

  • 索引是数据库中一种特殊的数据结构(如B+树),用于快速定位数据。
  • 作用:加速查询(WHERE、JOIN、ORDER BY)、强制唯一性(唯一索引)、优化聚合操作(GROUP BY)。

2、 为什么索引能提高查询速度?

索引通过有序数据结构(如B+树) 减少磁盘I/O次数。无需全表扫描,直接定位数据位置

3、 什么样的信息适合成为索引?什么样的信息不适合成为索引?

适合成为索引:

  • 高频查询字段(WHERE、JOIN条件)
  • 高区分度字段(如用户ID、手机号,重复值少)
  • 排序字段(ORDER BY)
  • 外键字段
  • 不适合成为索引:

    • 低区分度字段(如性别、状态标志)
    • 频繁修改的字段(索引维护成本高)
    • 大文本字段(如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

    全部评论

    相关推荐

    评论
    1
    6
    分享

    创作者周榜

    更多
    牛客网
    牛客网在线编程
    牛客网题解
    牛客企业服务