①、选择正确的存储引擎
MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要 update 一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。
InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。
②、固定长度的表会更快
表中没有如下类型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了,这样,MySQL 引擎会用另一种方法来处理。
固定长度的表会提高性能,因为 MySQL 搜寻得会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量的,所以读取的自然也会很快。而如果字段不是定长的,那么,每一次要找下一条的话,需要程序找到主键。
并且,固定长度的表也更容易被缓存和重建。不过,唯一的副作用是,固定长度的字段会浪费一些空间,因为定长的字段无论你用不用,他都是要分配那么多的空间。
使用“垂直分割”技术(见下一条),你可以分割你的表成为两个一个是定长的,一个则是不定长的。
③、垂直分割/主子表分家
“垂直分割”是一种把数据库中的表按列变成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的。(以前,在银行做过项目,见过一张表有100多个字段,很恐怖)
示例一:在 Users 表中有一个字段是家庭地址,这个字段是可选字段,相比起,而且你在数据库操作的时候除了个人信息外,你并不需要经常读取或是改写这个字段。那么,为什么不把他放到另外一张表中呢? 这样会让你的表有更好的性能,大家想想是不是,大量的时候,我对于用户表来说,只有用户ID,用户名,口令,用户角色等会被经常使用。小一点的表总是会有好的性能。
示例二: 你有一个叫 “last_login” 的字段,它会在每次用户登录时被更新。但是,每次更新时会导致该表的查询缓存被清空。所以,你可以把这个字段放到另一个表中,这样就不会影响你对用户 ID,用户名,用户角色的不停地读取了,因为查询缓存会帮你增加很多性能。
实例三:主子表分家,避免大胖子表。以前我们将所有的商品信息都堆在一张表导致它变成了一个大胖子,在关联查询的时候很容易形成性能瓶颈,后来我们把商品名称商品价格等核心字段放在主表,而把商品描述放在拓展表,表结构一瘦身性能咔咔起飞。
另外,你需要注意的是,这些被分出去的字段所形成的表,你不会经常性地去 Join 他们,不然的话,这样的性能会比不分割时还要差,而且,会是极数级的下降。
④、核心字段的冗余
用空间换时间,商品名称是一个高频字段,订单表在存储商品 ID 的时候,我们顺带的冗余商品的名称, 能够避免关联查询。
⑤、数据的删除
使用回收站模式, 千万别直接 delete 数据,一旦物理删除,恢复起来费时又费力。
聪明的做法是加个 is_delete 的字段,想恢复的时候就改回"N",妈妈再也不担心丢数据。
⑥、更新数据的时候顺手更新时间戳字段
在需要获取增量数据的时候,这个时间字段就是你的火眼金睛。
没有它你无法感知最新数据的变化,需要每次全表对比。
有了它你只需要加 where 时间字段大于上次的执行时间就能很快的锁定所有的新数据,查询效率呈指数级上升。
mysql 第6.7章 性能优化-设计表时的性能优化