最近公司规范数据库方面的一些东西,老程序员告诉我mysql里不许使用null,说是含null值的列无法索引,对性能影响很大。我第一次据说这个,对此将信将疑,以前用null并索引并无感受到不妥,多是数据量小吧。因而我去google了一顿,可是并无找到权威的说法。mysql
V2EX——关于null的索引不生效的传说是真的么?git
by shiny:
因为数据库的复杂性,以讹传讹的空间很是大,快遇上中医养生了。避免使用 NULL 的理由,在高性能MySQL里有提到一段。建议你们多读些书,少看网上的奇技淫巧。特地把书翻出来摘录了下以供参考:
要尽可能避免 NULL
要尽量地把字段定义为 NOT NULL。即便应用程序无须保存 NULL(没有值),也有许多表包含了可空列(Nullable Column),这仅仅是由于它为默认选项。除非真的要保存 NULL,不然就把列定义为 NOT NULL。
MySQL难以优化引用了可空列的查询,它会使索引、索引统计和值更加复杂。可空列须要更多的储存空间,还须要在MySQL内部进行特殊处理。当可空列被索引的时候,每条记录都须要一个额外的字节,还可能致使 MyISAM 中固定大小的索引(例如一个整数列上的索引)变成可变大小的索引。
即便要在表中储存「没有值」的字段,仍是有可能不使用 NULL 的。考虑使用 0、特殊值或空字符串来代替它。
把 NULL 列改成 NOT NULL 带来的性能提高很小,因此除非肯定它引入了问题,不然就不要把它看成优先的优化措施。而后,若是计划对列进行索引,就要尽可能避免把它设置为可空。
stackoverflow——NULL in MySQL (Performance & Storage)程序员
by Arian Acosta:
Advantage of using NULLS over Empty Strings or Zeros:
1 NULL requires 1 byte
1 Empty String requires 1 byte (assuming VARCHAR)
1 Zero requires 4 bytes (assuming INT)
You start to see the savings here:
8 NULLs require 1 byte
8 Empty Strings require 8 bytes
8 Zeros require 32 bytes
On the other hand, I suggest using NULLs over empty strings or zeros, because they're more organized, portable, and require less space. To improve performance and save space, focus on using the proper data types, indexes, and queries instead of weird tricks.
中英文用户们对此都是争论不休,在群里问了一下老前辈,前辈表示mysql这个东西很玄乎,仍是本身写性能测是最靠谱,说的好那么开始写吧。github
https://github.com/win5do/pla...golang
进入文件所在目录运行:go test -v -run=none -bench=. -benchmemsql
mysql5.7 mock100w条数据 null彻底没影响数据库
mysql5.5 仍是100w条less
储存空间占用也是相同的,null占空间 ‘’一样占空间工具
为何要用golang,由于最近在学习golang,经过写代码来加深对语言的理解。并且golang自带测试工具,作性能测试很是方便。性能
第一个坑,之前没用过golang链接数据库,写create语句的时候一直提示syntax error,仔细检查了好几遍,没有错误啊。后来翻了翻文档发现链接是加上multiStatements=true参数才能使用多行sql。
第二个坑就是insert语句拼接的太长会致使write pipe broken,mock50000行时没问题,但100000行就报错了,解决办法就是分块插入,10000行插一下。
第三个坑,就是query以后是要close的
测试了mysql5.7和5.5版本,null对索引没有影响,甚至容许null的还快一丢丢(或者说个人测试太过于简单,不成立?)。不要一棒子把null打死,该用就用,null的语义化很好,配合orm使用基本无痛。好比时间列,不用null用个0000-00-00不要太蛋痛。
那句老话:
过早的优化是万恶之源
仅凭中医理论优化更是无可救药
更重要的,用golang写代码真的很cool