mysql优化不可缺少的方法

现在我们都知道mysql优化这块在项目应用中已经是不可缺少的一部分,所以现在公司对网站优化这块尤为重视,下面我为大家分享一下一些重要的优化技巧。

MYSQL 三范式
mysql的三范式可以理解成一个规则,遵守这个规则会减少数据的冗余,但是也要根据情况而定,但是有些时候一昧的追求范式减少冗余,反而会降低数据读写的效率
一、第一范式(无重复的列) 
定义:数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。如果实体中的某个属性有多个值时,必须拆分为不同的属性 
通俗理解:一个字段只存储一项信息
二、第二范式(属性完全依赖于主键) 
定义:满足第一范式前提,当存在多个主键的时候,才会发生不符合第二范式的情况。比如有两个主键,不能存在这样的属性,它只依赖于其中一个主键,这就是不符合第二范式 通俗理解:任意一个字段都只依赖表中的同一个字段 
三、第三范式(属性不能传递依赖于主属性) 
定义:表中的每一列都要与主键直接相关,而不是间接相关(表中的每一列只能依赖于主键)
例如:订单表中需要有客户相关信息,在分离出客户表之后,订单表中只需要有一个用户ID即可,而不能有其他的客户信息,因为其他的用户信息是直接关联于用户ID,而不是关联于订单ID。

1、建表阶段是非常重要的一个环节,建表的结构好坏,后期会直接影响整体性能,所以这步尤为重要,首先我们在创建表的时候选择合适的存储引擎(最常用的引擎有innodb myisam 他两的区别在在于一个读快一个写入快),并且在创建字段时选择合适的类型和长度,另外尽量把字段都设置为no Tnull 这样在查询时候数据库不用去比较null值了。
注释:1.是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;
 2.如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读写也挺频繁,请使用InnoDB(数据块,INNODB要缓存,MYISAM只缓存索引块,  这中间还有换进换出的减少;innodb寻址要映射到块,再到行,MYISAM记录的直接是文件的OFFSET,定位比INNODB要快)
 3.如果数据表涉及业务逻辑多,增删改操作多,就用innodb
2、在查询数据时经量不要使用select *  而是 使用你需要的字段名来代替*号,这样会大大提高查询效率。
3、给适合的字段加上索引可以提高查询速度简单来说,索引就好比一本书的目录,你只要浏览标题就可以快速的找到具体内容是放在哪一页。也就好似说select查找的时候不需要直接取搜索表,只需要查找索引,就可以直接定位到你想要查找的内容。所以某个字段你总要经常用来做搜索,那么,请为其建立索引吧。但是有一个问题加了索引之后会对增加删除修改等降低效率。并且还有一些情况会导致索引失败(1)用like查询时索引会失败(2)使用or时候如果两边有一个没有索引也会导致索引失败所以尽量使用 in 或者union 来代替or这样会更高效。如果有百万数量时候结合xunsearch和like结合使用少用索引。
主键索引与唯一索引的区别
  1. 主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。
  2. 主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。
  3. 唯一性索引列允许空值,而主键列不允许为空值。
  4. 主键列在创建时,已经默认为空值 + 唯一索引了。
  5. 一个表最多只能创建一个主键,但可以创建多个唯一索引。
  6. 主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。
  7. 主键可以被其他表引用为外键,而唯一索引不能
4、对数据进行分页优化,这样每次请求将不会是全部内容大大减轻了数据库的压力。
5、使用join代替子查询,因为join不需要另外在创建临时表,从而增加了效率;
注释:子查询:把内层查询结果当作外层查询的比较条件
执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,这里多了一个创建和销毁临时表的过程。
可以使用连接查询(JOIN)代替子查询,连接查询不需要建立临时表,因此其速度比子查询快
6、在查询多条语句时,如果需求结果字段数目相同,那么可以使用union 关键字进行多条连接查询例如:select name,pwd from biao1 union select name,pwd biao2 进行连接查询 这样也会提高效率。
7、如果在写入数据时,需要同时对多个表改变数据,那么要加上事物,因为事物的特点就是要么都成功要么都失败这保证了数据的原子性。
8、分区,就是按照一定的规则, 将一个数据库表分解成很多细小的表, 这些细小的表可以是物理的分区, 就是在不同的位置. 但是站在应用的角度来看,分区又是透明的, 整体上看起来还是一个表,不影响使用
9、分表,分表又分为水平和垂直分表,水平分表是在数据量很多的时候,把数据量分开存放,而垂直拆分的话发生在字段多的情况下,根据需求进行垂直拆分,拆分后数量是一致的。

碎片产生的原因 

1)表的存储会出现碎片化,每当删除了一行内容,该段空间就会变为空白、被留空,而在一段时间
内的大量删除操作,会使这种留空的空间变得比存储列表内容所使用的空间更大;
(2)当执行插入操作时,MySQL会尝试使用空白空间,但如果某个空白空间一直没有被大小合适的数
据占用,仍然无法将其彻底占用,就形成了碎片;
清除碎片操作会暂时锁表,数据量越大,耗费的时间越长,可以做个脚本,定期在访问低谷时间执行,
例如每周三凌晨,检查DATA_FREE字段,大于自己认为的警戒值的话,就清理一次。

mysql主从复制

原理:主从复制一共有三个进程,从库生成两个线程,一个I/O线程,一个SQL线程;
i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中;
主库会生成一个 log dump 线程,用来给从库 i/o线程传binlog; 
SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致;
mysql优化不可缺少的方法_第1张图片

下面我来说一下实战中遇到的问题

这个问题就是如何去优化千万级的表,经过分析我们当时对优化的步骤分为以下几步:
1、优化sql语句和索引;
2、加入缓存例如memcache或者redis
3、如果实现以上两条以后发现还是慢那么如果多台服务器时可以实现主从复制,读写分离。
4、以上做完还是慢那就使用mysql自带分区。
5、如果都不能解决,那最后只能使用绝招了,那么就是水平分表,这样就需要改动代码了。
通过以上点我总结了一下,在如果问题时先从最简单的开始,逐步开始优化。

你可能感兴趣的:(mysql)