规则1:通常状况能够选择MyISAM存储引擎,若是须要事务支持必须使用InnoDB存储引擎。mysql
注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的全部字段的长度之和不能超过1000字节。另外MyISAM数据和索引是分开,而InnoDB的数据存储是按聚簇(cluster)索引有序排列的,主键是默认的聚簇(cluster)索引,所以MyISAM虽然在通常状况下,查询性能比InnoDB高,但InnoDB的以主键为条件的查询性能是很是高的。sql
规则2:命名规则。数据库
数据库和表名应尽量和所服务的业务模块名一致缓存
服务与同一个子模块的一类表应尽可能以子模块名(或部分单词)为前缀或后缀并发
表名应尽可能包含与所存放数据对应的单词性能
字段名称也应尽可能保持和实际数据相对应测试
联合索引名称应尽可能包含全部索引键字段名或缩写,且各字段名在索引名中的顺序应与索引键在索引中的索引顺序一致,并尽可能包含一个相似idx的前缀或后缀,以代表期对象类型是索引。优化
约束等其余对象也应该尽量包含所属表或其余对象的名称,以代表各自的关系spa
规则3:数据库字段类型定义设计
常常须要计算和排序等消耗CPU的字段,应该尽可能选择更为迅速的字段,如用TIMESTAMP
(4个字节,最小值1970-01-01 00:00:00)代替Datetime
(8个字节,最小值1001-01-01 00:00:00),经过整型替代浮点型和字符型
变长字段使用varchar
,不要使用char
对于二进制多媒体数据,流水队列数据(如日志),超大文本数据不要放在数据库字段中
规则4:业务逻辑执行过程必须读到的表中必需要有初始的值。避免业务读出为负或无穷大的值致使程序失败
规则5:并不须要必定遵照范式理论,适度的冗余,让Query尽可能减小Join
规则6:访问频率较低的大字段拆分出数据表。有些大字段占用空间多,访问频率较其余字段明显要少不少,这种状况进行拆分,频繁的查询中就不须要读取大字段,形成IO资源的浪费。
规则7:大表能够考虑水平拆分。大表影响查询效率,根据业务特性有不少拆分方式,像根据时间递增的数据,能够根据时间来分。以id划分的数据,可根据id%数据库个数的方式来拆分。
规则8:业务须要的相关索引是根据实际的设计所构造sql语句的where条件来肯定的,业务不须要的不要建索引,不容许在联合索引(或主键)中存在多于的字段。特别是该字段根本不会在条件语句中出现。
规则9:惟一肯定一条记录的一个字段或多个字段要创建主键或者惟一索引,不能惟一肯定一条记录,为了提升查询效率建普通索引
规则10:业务使用的表,有些记录数不多,甚至只有一条记录,为了约束的须要,也要创建索引或者设置主键。
规则11:对于取值不能重复,常常做为查询条件的字段,应该建惟一索引(主键默认惟一索引),而且将查询条件中该字段的条件置于第一个位置。没有必要再创建与该字段有关的联合索引。
规则12:对于常常查询的字段,其值不惟一,也应该考虑创建普通索引,查询语句中该字段条件置于第一个位置,对联合索引处理的方法一样。
规则13:业务经过不惟一索引访问数据时,须要考虑经过该索引值返回的记录稠密度,原则上可能的稠密度最大不能高于0.2,若是稠密度太大,则不合适创建索引了。
当经过这个索引查找获得的数据量占到表内全部数据的20%以上时,则须要考虑创建该索引的代价,同时因为索引扫描产生的都是随机I/O,生其效率比全表顺序扫描的顺序I/O低不少。数据库系统优化query的时候有可能不会用到这个索引。
规则14:须要联合索引(或联合主键)的数据库要注意索引的顺序。SQL语句中的匹配条件也要跟索引的顺序保持一致。
注意:索引的顺势不正确也可能致使严重的后果。
规则15:表中的多个字段查询做为查询条件,不含有其余索引,而且字段联合值不重复,能够在这多个字段上建惟一的联合索引,假设索引字段为 (a1,a2,...an),则查询条件(a1 op val1,a2 op val2,...am op valm)m<=n
,能够用到索引,查询条件中字段的位置与索引中的字段位置是一致的。
规则16:联合索引的创建原则(如下均假设在数据库表的字段a,b,c上创建联合索引(a,b,c))
联合索引中的字段应尽可能知足过滤数据从多到少的顺序,也就是说差别最大的字段应该房子第一个字段
创建索引尽可能与SQL语句的条件顺序一致,使SQL语句尽可能以整个索引为条件,尽可能避免以索引的一部分(特别是首个条件与索引的首个字段不一致时)做为查询的条件
Where a=1,where a>=12 and a<15,where a=1 and b<5 ,where a=1 and b=7 and c>=40为条件能够用到此联合索引;而这些语句where b=10,where c=221,where b>=12 and c=2则没法用到这个联合索引。
当须要查询的数据库字段所有在索引中体现时,数据库能够直接查询索引获得查询信息无须对整个表进行扫描(这就是所谓的key-only),能大大的提升查询效率。
当a,ab,abc与其余表字段关联查询时能够用到索引
当a,ab,abc顺序而不是b,c,bc,ac为顺序执行Order by或者group不要时能够用到索引
如下状况时,进行表扫描而后排序可能比使用联合索引更加有效
a.表已经按照索引组织好了
b.被查询的数据站全部数据的不少比例。
规则17:重要业务访问数据表时。但不能经过索引访问数据时,应该确保顺序访问的记录数目是有限的,原则上不得多于10.
规则18:合理构造Query语句
Insert语句中,根据测试,批量一次插入1000条时效率最高,多于1000条时,要拆分,屡次进行一样的插入,应该合并批量进行。注意query语句的长度要小于mysqld的参数 max_allowed_packet
查询条件中各类逻辑操做符性能顺序是and,or,in,所以在查询条件中应该尽可能避免使用在大集合中使用in
永远用小结果集驱动大记录集,由于在mysql中,只有Nested Join一种Join方式,就是说mysql的join是经过嵌套循环来实现的。经过小结果集驱动大记录集这个原则来减小嵌套循环的循环次数,以减小IO总量及CPU运算次数
尽可能优化Nested Join内层循环。
只取须要的columns,尽可能不要使用select *
仅仅使用最有效的过滤字段,where 字句中的过滤条件少为好
尽可能避免复杂的Join和子查询
Mysql在并发这块作得并非太好,当并发量过高的时候,总体性能会急剧降低,这主要与Mysql内部资源的争用锁定控制有关,MyIsam用表锁,InnoDB好一些用行锁。
规则19:应用系统的优化
合理使用cache,对于变化较少的部分活跃数据经过应用层的cache缓存到内存中,对性能的提高是成数量级的。
对重复执行相同的query进行合并,减小IO次数。
事务相关性最小原则