V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
LeeReamond
V2EX  ›  问与答

数据库中的 null 对性能有什么影响?

  •  1
     
  •   LeeReamond · 2021-04-16 03:38:28 +08:00 · 2536 次点击
    这是一个创建于 1351 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题,相关话题 https://v2ex.com/t/770788#reply84

    我看里面一路下来很多大佬回复,说 null 改成 not null,一不能节省体积,二不能优化索引

    说实话其实有点毁三观,这么多年学的尽量不要用 null 是错的?
    16 条回复    2021-04-16 13:35:14 +08:00
    xupefei
        1
    xupefei  
       2021-04-16 06:29:09 +08:00 via iPhone
    事实就是没啥影响。
    levelworm
        2
    levelworm  
       2021-04-16 06:31:05 +08:00 via Android
    我觉得也看数据库吧
    LeeReamond
        3
    LeeReamond  
    OP
       2021-04-16 07:10:30 +08:00
    @xupefei

    等大佬来一个详解。

    以往一般处理是,通常业务环境不会用到数据类型的满集,比如 IP 这种 u32 每一个比特都映射到的很少。比如存年龄,那就以-1 代表未输入。如果真的没有影响的话,null 确实可以减少开发逻辑啊。

    另外不晓得这个结论对 mysql 两个引擎是否通用,对 pgsql 和 oracle 是否也通用
    Justin13
        4
    Justin13  
       2021-04-16 08:08:59 +08:00 via Android
    如果认为数据库只是记录数据,查询也很简单,用 null 很合理,也没问题
    如果认为 null 有意义,当正常值用,但是查询还特别复杂,JOIN 很多,那就要命了,会很慢。
    所以具体怎么做,看实际需求,不能一概而论。
    qping
        5
    qping  
       2021-04-16 08:20:13 +08:00
    @Justin13 #4 请教下,JOIN 很多,是指 JOIN 的字段如果有 null 值会影响性能?
    Justin13
        6
    Justin13  
       2021-04-16 08:25:13 +08:00 via Android
    @qping 如果认为 null 是有效值,where 中就会有 or xxx.a is null and yyy.a is null
    这里必然会有 or,如果 where 条件再涉及多个字段,就会导致索引失效。
    xiangyuecn
        7
    xiangyuecn  
       2021-04-16 08:27:03 +08:00
    个人理解:

    很多情况下,null 的存在只会产生歧义,没有任何实际作用,not null 才应该被默认

    比如常用字符串、数字,大部分情况下都应该首选 not null,插入数据必须给值或提供默认值

    存在 null 值时,你的字符串、数字类型,判断一个是不是空的,sql 编写异常困难,工作量呈指数级上升

    not null 时,只需要 field!=0 field!='',有 null 时,你还要加上 or field is null,不然 null 这个歧义很难解决

    -----

    not null 和 默认值 是两个概念,必须给值的首选必须插入时提供值,不是依赖默认值

    -----

    那种没法提供默认值,插入时又无法提供值的,才应当允许为 null,比如:只能后续 update 才能给值的 datetime 类型
    Justin13
        8
    Justin13  
       2021-04-16 08:39:24 +08:00 via Android
    简单说就是,如果你的 SQL 中,可能会出现 or xxx is null 那就尽量避免使用 null 值,否则没啥影响。
    mm163
        9
    mm163  
       2021-04-16 08:55:51 +08:00
    参与逻辑的字段最好允许 null, null 判断很麻烦,很容易产生 bug 。
    wellsc
        10
    wellsc  
       2021-04-16 09:02:22 +08:00
    @mm163 看不懂
    wakzz
        11
    wakzz  
       2021-04-16 09:11:17 +08:00   ❤️ 1
    null 对索引有影响已经是老皇历了,mysql 的 innodb 引擎在 5.5 就已经做过优化了,null 字段和 not null 字段在索引查询方面几乎没有性能区别了。所以现在更关注 null 值和 not null 值对业务场景的落地问题。
    raaaaaar
        12
    raaaaaar  
       2021-04-16 09:11:30 +08:00 via Android
    大概就是判断 null 时会掉索引吧
    wakzz
        13
    wakzz  
       2021-04-16 09:13:43 +08:00
    @Justin13 is null 查询没问题,应该避免的是 or 这个查询关键字。
    wakzz
        14
    wakzz  
       2021-04-16 09:17:09 +08:00
    mysql 的索引是基于预估成本进行选择的,is null 、is not null 、>、<、<>等查询条件并不影响索引的使用。多个索引存在时,mysql 只会选择它预估成本最低的索引,当然既然是预估,也存在 mysql 预估错误选择了非最优索引的情况。
    mlcq
        15
    mlcq  
       2021-04-16 09:27:11 +08:00
    @wakzz #14 是的,都是根据 cost 来选择的
    Aksura
        16
    Aksura  
       2021-04-16 13:35:14 +08:00
    看具体什么数据库,具体数据什么含义。世上数据库不是只有 MySQL,它的实现(及其带来的“最佳实践”)也不是放之四海皆准的真理。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5449 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 08:34 · PVG 16:34 · LAX 00:34 · JFK 03:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.