数据库中的 null 对性能有什么影响? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LeeReamond
V2EX    问与答

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

  •  1
     
  •   LeeReamond 2021-04-16 03:38:28 +08:00 3068 次点击
    这是一个创建于 1705 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题,相关话题 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     Solana     1453 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 16:43 PVG 00:43 LAX 08:43 JFK 11:43
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86