Bohr-L Bohr-L
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

刘博

I'm a slow walker, But I never walk backwards.
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据处理与存储类

  • Spring 生态类

  • 缓存问题类

  • 多线程类

  • JVM 类

  • MySQL 类

    • MySQL 为什么一定要有一个主键
    • MySQL 中的 RR 隔离级别,到底有没有解决幻读问题
    • MySQL 的行级锁到底锁的是什么东西?
    • 存储 MD5 值应该用 VARCHAR 还是用 CHAR?
    • 数据库的三范式是什么?
    • 说说 InnoDB 与 MyISAM 的区别
    • drop、truncate、delete 的区别
    • 聊一聊数据库事务机制
    • 聊一聊 MySQL 中的关联查询
    • 事务隔离级别有哪些?MySQL 的默认隔离级别是什么
    • 分库分表之后,id 主键如何处理?
    • 说说在 MySQL 中一条查询 SQL 是如何执行的?
    • 讲解下 DDL、DML、DCL
    • 存储过程和触发器的作用
    • MySQL 如何行转列和列转行
    • 如何查看 SQL 的执行计划
    • union 和 unionAll 的区别
    • having 和 where 的区别
    • 常见的索引原则
    • MySQL 中的 IN 和 EXISTS 子句有什么区别?
    • MySQL 如何处理 NULL 值,对性能有什么影响?
      • 如何在 MySQL 中处理和避免全表扫描?
      • MySQL 中的表空间是什么,它的作用是什么?
      • 在 MySQL 中,如何优化 ORDER BY 查询?
    • Java 8 + 特性类

    • 其他技术类

    • 常见面试题
    • MySQL 类
    刘博
    2025-12-29
    目录

    MySQL 如何处理 NULL 值,对性能有什么影响?

    # 1. MySQL 对 NULL 值的处理规则

    NULL 是 MySQL 中表示 “未知值” 的特殊标记(不同于空字符串''、0),处理规则如下:

    • 比较运算:NULL 与任何值比较(=、!=、>、<)结果均为 NULL(非 TRUE/FALSE),需用IS NULL/IS NOT NULL判断;
      • 示例:WHERE age = NULL(无结果),正确写法WHERE age IS NULL;
    • 聚合函数:聚合函数(COUNT、SUM、AVG)会忽略 NULL 值;
      • 示例:COUNT(age)(忽略 age 为 NULL 的行),COUNT(*)(不忽略 NULL 行,统计所有行);
    • 索引处理:B-Tree 索引(InnoDB 默认索引)支持存储 NULL 值,但 NULL 值会被当作一个特殊值存储在索引树的最左侧(MySQL 8.0 后可配置排序);
    • 唯一索引:唯一索引允许存储多个 NULL 值(因 NULL≠NULL,不违反唯一性约束);
    • 字符串处理:NULL 与字符串拼接(CONCAT('a', NULL))结果为 NULL,需用IFNULL处理(CONCAT('a', IFNULL(col, '')))。

    # 2. NULL 值对性能的影响

    • 1. 索引效率下降:
      • NULL 值会增加索引树的复杂度(需单独存储 NULL 值节点),导致索引扫描行数增加;
      • 使用IS NULL/IS NOT NULL查询时,索引可能失效(如WHERE age IS NULL,若 age 字段 NULL 值较多,MySQL 可能选择全表扫描);
    • 2. 排序与分组性能差:
      • 排序时,NULL 值会被排在最前或最后(取决于排序方向),增加排序开销;
      • 分组时,所有 NULL 值会被分为一组,但分组效率低于非 NULL 值;
    • 3. 聚合函数计算额外开销:
      • 聚合函数(如 SUM、AVG)需先判断值是否为 NULL,再进行计算,比处理非 NULL 值多一步操作;
    • 4. 存储开销增加:
      • 部分数据类型存储 NULL 值需额外空间(如 VARCHAR 存储 NULL 时,需存储长度标识为 NULL);
      • 复合索引中,NULL 值会导致索引过滤性下降(如idx_age_name (age, name),age 为 NULL 时,name 字段无法使用索引)。

    # 3. 优化建议:避免 NULL 值

    • 1. 字段设置为 NOT NULL:为字段设置默认值(如age INT NOT NULL DEFAULT 0、name VARCHAR(20) NOT NULL DEFAULT ''),用默认值替代 NULL;
    • 2. 用特殊值表示 NULL 含义:如状态字段用-1表示 “未知”,时间字段用'1970-01-01'表示 “未设置”,避免使用 NULL;
    • 3. 查询时避免 IS NULL/IS NOT NULL:用默认值替代 NULL 后,查询条件改为WHERE age = 0(替代age IS NULL)、WHERE age != 0(替代age IS NOT NULL),确保索引有效;
    • 4. 索引设计优化:若字段必须存储 NULL 值,避免将其作为联合索引的前导字段(如idx_name_age (name, age),name 非 NULL,age 可 NULL),提升索引过滤性。

    上次更新: 12/30/2025
    MySQL 中的 IN 和 EXISTS 子句有什么区别?
    如何在 MySQL 中处理和避免全表扫描?

    ← MySQL 中的 IN 和 EXISTS 子句有什么区别? 如何在 MySQL 中处理和避免全表扫描?→

    最近更新
    01
    CPU 使用率较高排查和解决
    12-29
    02
    JVM OOM 问题如何排查和解决
    12-29
    03
    接口防刷怎么实现?
    12-29
    更多文章>
    Theme by Vdoing | Copyright © 2025-2026 Bohr-L's note
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式