MySQL数据库设计优化
数据库设计并不是一味的范式化,应该从实际需求出发,以性能提升为根本目标来展开设计工作,很多时候为了尽可能提高性能,必须做反范式设计。
1.适度冗余——让Query尽量减少Join
2.大字段拆分单独表
由于大字段存放的内容较多,大部分情况都占整条记录的80%以上,而数据库中数据在数据文件中的格式一般都是以单条记录为单位来存放的。也就是说,如果要查询某些记录的某几个字段,数据库并不是只须访问要查询的那几个字段,而是须要读取其他所有字段(可以在索引中完成整个查询的情况除外)。这样,就不得不读取包括大字段在内的很多并不相干的数据。而由于大字段所占的空间比例非常大,自然所浪费的IO资源也就相当大了。在分拆出大字段之前还须考虑的第二个因素——访问频率。前面已经介绍了,决定一个字段是否要分拆出去,除了“大”之外,还要“频率低”才行,当然,这里的“频率低”只是“相对频率”而已。如果已经确定有大字段须要分拆出主表,对于其他字段,只要和大字段一样满足访问频率相对于表中其他字段低很多的,都可以和大字段同时分拆出来。
3.大表水平分拆——基于类型的分拆优化
如果博客需要增加一个置顶帖功能,需要的字段和现有文章表字段相同,可能有的人会在现有文章表里增加一个类型字段用以区分普通贴和置顶帖。
但是由于文章表里的数据量大,而且置顶帖访问频率高、量少,每次页面展示查询都需要查询两次大表才能得到数据,Query成本会相对有些高。所以需要创建一张新表存放置顶帖。
4.避免使用外键
外键会导致父表和子表之间耦合,十分影响SQL性能,出现过多的锁等待,甚至造成死锁
5.表必须有主键,例如自增主键
从性能的角度来说,使用UUID作为主键是个最不好的方法,它会使插入变得随机
6.禁止使用分区表
使用分区表查询的字段必须是分区键,否则会遍历所有的分区表,并不会带来性能上的提升。此外分区表在物理结构上仍旧是一张表,此时我们更改表结构,一样不会带来性能上的提升。所以应采用切表的形式做拆分,如程序上需要对历史数据做查询,可通过union all的方式关联查询。另外随着时间的推移,历史数据表不再需要,只需要在从库上dump出来,即便捷地迁移至备份机
7.字段尽可能不定义为NULL,提供默认值
NULL值很难进行查询优化,它会使索引统计更加复杂,还需要mysql内部进行特殊处理
8.尽可能不使用TEXT、BLOB类型