法则一:一般情况下,可以选择MyISAM存储引擎。如果需要事务支持,就必须使用InnoDB存储引擎。注意:MyISAM存储引擎B树索引有一个很大的限制:参与索引的所有字段的长度之和不能超过1000字节。另外,MyISAM的数据和索引是分离的,而InnoDB的数据存储是按照簇索引有序排列的,主键是默认的簇索引。因此,虽然MyISAM的查询性能普遍高于InnoDB,但是InnoDB基于主键的查询性能是非常高的。规则2:命名规则。1、数据库和表的名称尽量与其服务的业务模块名称一致。2.服务于同一个子模块的一类表,尽可能使用子模块名(或一些单词)作为前缀或后缀。3.表名尽量包含存储数据对应的词4.字段名也尽量与实际数据保持对应。5.联合索引名尽量包含所有索引键字段名或缩写,且索引名中各字段名的顺序应与索引键在索引中的索引顺序一致,并尽量包含类似于idx的前缀或后缀,以指示预期对象的类型是索引。6.约束等其他对象也尽量包含表名或所属其他对象的名称,以表明各自的关系规则3:数据库字段类型定义1.对于经常需要计算排序的字段等消耗CPU的字段,应该尽量选择更快速的字段,比如用TIMESTAMP(4字节,最小值1970-01-0100:00:00)代替Datetime(8字节,最小值1001-01)-0100:00:00),通过整数替换浮点和字符类型2.对可变长度字段使用varchar而不是char3。对于二进制多媒体数据、管道数据(如日志)、超大文本数据,不要放在数据库字段中。规则四:业务逻辑执行必须要读到的表必须有初始值。避免导致程序失败的业务读数为负值或无限值。规则五:不必遵守范式理论,适度冗余,让Query尽量减少join。法则六:对访问频率低的大字段拆分数据表。一些大字段占用空间大,访问频率明显低于其他字段。在这种情况下,拆分字段不需要在频繁查询时读取大字段,造成IO资源的浪费。规则七:大表可以考虑横向拆分。大表影响查询效率。根据业务特点有多种拆分方式。比如按时间增加的数据,可以按时间划分。按id划分的数据可以按照id%数据库个数进行拆分。规则八:业务需要的相关索引根据实际设计中构造的SQL语句的where条件确定。如果业务不需要,则不建索引,联合索引(或主键)中不允许有多个字段。特别是该字段根本不会出现在条件语句中。规则9:要唯一确定一条记录的一个或多个字段,必须建立主键或唯一索引。一条记录不能唯一确定。为了提高查询效率,应该建立普通的索引。对于一条记录,还必须为约束创建索引或主键。规则11:对于取值不能重复且经常作为查询条件的字段,应建立唯一索引(主键默认唯一索引),并在查询条件中放置该字段的条件在第一个位置。无需创建与该字段相关的联合索引。规则十二:对于经常查询的字段,其值不唯一的,也应该考虑建立一个公共索引。将字段条件放在查询语句的第一个位置,联合索引处理方法相同。规则十三:业务通过非唯一索引访问数据时,需要考虑索引值返回的记录密度。原则上,可能的密度不能高于0.2。密度太大不适合建索引。当通过该索引查找得到的数据量占表中所有数据的20%以上时,需要考虑建立索引的成本。同时,由于索引扫描产生随机I/O,其效率高于整表。扫描的顺序I/O要低得多。数据库系统在优化查询时可能不会使用这个索引。规则十四:需要联合索引(或联合主键)的数据库要注意索引的顺序。SQL语句中的匹配条件也要和索引的顺序一致。注意:索引的不正确对齐也会导致严重的后果。规则十五:以表中多个字段查询作为查询条件,不包含其他索引,字段的联合值不重复。可以对这多个字段建立唯一联合索引,假设索引字段为(a1,a2,...an),查询条件(a1opval1,a2opval2,...amopvalm)m<=n,可以使用索引,查询条件中字段的位置与索引中的字段位置一致。规则十六:建立联合索引的原则(以下假设在数据库表的字段a,b,c上建立联合索引(a,b,c))1.联合索引中的字段应该尽量满足从多到少的过滤数据,也就是说,差异最大的字段应该是第一个字段。2.建索引的顺序尽量与SQL语句的条件相同,使SQL语句尽可能基于整个索引,尽量避免使用索引的一部分(尤其是当***条件与索引的***字段不一致)作为查询条件3,Wherea=1,wherea>=12anda<15,wherea=1andb<5,wherea=1b=7和c>=40可以使用这个联合索引;whilewhereb=10,wherec=221,whereb>=12andc=2这些语句不能使用这个联合索引。4.当所有需要查询的数据库字段都反映在索引中时,数据库可以直接查询索引获取查询信息,而无需扫描整张表(这就是所谓的key-only),可以大大提高查询效率。当a、ab、abc与其他表字段关联时,可以使用索引5。当a、ab、abc依次代替b、c、bc、ac时,不需要orderby或group时可以使用orderby或group。索引6、在以下情况下,执行表扫描然后排序可能比使用联合索引更高效:a.该表已根据索引组织;规则17:重要业务访问数据表时。但当无法通过索引访问数据时,应保证顺序访问的记录数有限,原则上不超过10条。法则十八:合理构造Query语句1.在Insert语句中,根据测试,一次批量插入1000条记录时的效率***,当记录超过1000条时,需要拆分,同样的插入多次,需要批量合并。注意查询语句的长度要小于mysqld的参数max_allowed_pa??cket2,并且查询条件中各种逻辑运算符的执行顺序是and,or,in,所以在查询条件中,尽量避免使用in3在大集合中,总是用小的结果集驱动大的记录集,因为在mysql中,只有一种join方式,NestedJoin,也就是说mysql的join是通过嵌套循环实现的。利用以小结果集驱动大记录集的原则,减少嵌套循环的循环次数,从而减少IO总量和CPU运算次数。4.尝试优化NestedJoin的内循环。5、只取需要的列,尽量不要用select*6。只使用最有效的过滤字段。where子句中的过滤条件最好少一些。7.尽量避免复杂的Join和子查询。mysql在并发方面做得并不好,当并发量过高时,整体性能会急剧下降。这主要与Mysql内部资源的争用锁控制有关。MyIsam使用表锁,而InnoDB使用行锁更好。第十九条:应用系统的优化1.合理使用缓存。对于一些变化较少的活跃数据,通过应用层的缓存缓存在内存中,性能提升了一个数量级。2.合并重复执行的同一个查询,减少IO次数。3、最小交易相关性原则
