MySQL性能优化方案

欢迎访问个人我的博客:www.ifueen.commysql

MySql性能优化策略

关系型数据库的优化方案

关于MySQL的优化,大致方案能够分为如下步骤web

  1. 找出执行效率低的Sql
  2. 分析慢的Sql
  3. 进行优化

定位慢查询

找出执行效率慢的SQL(定位慢SQL)

首先要明白原理,实际上咱们在数据库上面所作的操做都会被日志记录下来,咱们在定位慢查询就须要去经过日志记录来找到究竟是哪条SQL效率慢算法

查询数据库状态的命令sql

运行了多久 show status like 'uptime';

CRUD的执行次数 
show status like '%Com_select%'
show status like '%Com_insert%'
show status like '%Com_update%'
show status like '%Com_delete%'

查询全部的链接数
show status like 'connections'

查询慢查询次数(数据库默认是10S,能够经过命令设置)
show status like 'slow_queries' 

查看和修改慢查询时间阈值
show variables like ‘long_query_time’ ; //能够显示当前慢查询时间
set long_query_time=1 ;//能够修改慢查询时间

开启慢查询记录日志

由于咱们的SQL服务默认是没有开启满记录日志的,因此咱们并不能查看慢查询相关的记录,须要咱们手动开启数据库

进入到mysql文件夹下的bin目录,经过cmd运行如下命令:mysqld.exe --safe-mode --slow-query-log性能优化

就能够开启慢查询记录的日志数据结构

慢记录日志的默认输出地址在my.ini文件中,一般默认是在C盘数据库设计

慢记录通常都会在开发和测试阶段开启,不要等到上线后再去检查svg

分析Sql语句

经过 explain 语句能够分析Sql语句性能

单机优化

经过表结构设计

数据库设计三范式

这是数据库在设计之初咱们默认都要遵照的规则

第一范式:数据表中的列是不可分割的一个总体

第二范式:表中的记录都须要一个惟一标识(一般是主键)

第三范式:表中不要有冗余数据,大致意思就是一张表中不能出现另外一张表除主键以外的字段

反三范式设计

有时候为了提升效率,有时候就必需要经过反三范式来进行设计,适当的保留冗余数据

对于存储设计,咱们一般有两种方式来进行设置

定长:会根据数据的类型来进行空间的分配,是固定的

边长:根据存储数据的大小来,用多少就分配多少

存储引擎

数据库的存储引擎分类:Innodb,MyISAM

Innodb和MyISAM的区别

  • Innodb支持事务,MyISAM不支持事务
  • MyISAM查询和添加较块,Innodb查询比较慢
  • Innodb支持外键,MyISAM不支持外键
  • 锁机制MyISAM用的是表锁,Innodb用的是行锁
  • MyISAM支持全文索引,Innodb不支持全文索引

索引

首先咱们要弄清楚一个概念:什么是索引,何时用索引?

索引是数据库优化的时候最物美价廉的东西,官方概念称是帮助MySQL提升查找效率的一种数据结构,可以帮咱们快速的定位查找到相应的位置

咱们通常在数据量过多的表中或者须要查询频率比较高的字段上加上索引

注意:对于增删改操做比较多的字段,不建议使用索引,即便查询频率较高

MyISAM和Innodb都只支持Btree索引算法,而MEMORY/HEAP同时支持Btree和HASH算法

索引分类

  • 普通索引:容许重复的出现,能够在任何字段上面添加
  • 惟一索引:要求添加索引的字段里面的内容必须是惟一的(如:身份证、电话号码、游戏ID、QQ号),容许内容为空
  • 主键索引:只能在主键上面添加的索引,要求非空且惟一
  • 全文索引:用来堆表中的文本域(bigtext,char,text)进行索引,全文索引针对MyISAM有用

此外,咱们害能够建立复合索引(多列索引,就是在多个列上面建立同样的索引

复合索引使用事项:

  • 没有使用第一部分就不会使用索引
  • 对于使用了like的查询,只有前置匹配才可使用到复合索引
  • 若是条件中存在or,则索引失效
  • 若是条件中存在<>,则索引失效
  • 若是列类型是字符串,那么必定要用引号引发来,不然也会致使索引失效

分表

分表的方式有垂直分表和水平分表两种

垂直分表

垂直分表是根据字段进行分表,咱们一般会遇到这种需求,有些表记录的数据并非不少,可是字段却很是的多,每次查询起来会执行大量的I/O,影响性能,这时候咱们就能够进行垂直分表

好比:如今一个用户有许多字段信息,可是有些又不太经常使用,就能够经过id,把姓名,电话,地址等分一个表,把签名,收藏等经过id进行垂直分表,分为另外一张表,两张表的id是同一个

水平分表

水平分表是根据记录来进行分表,若是一个表的记录太多的话,不用想,天然会影响到查询的效率,好比上千万条,并且须要常常检索,那么咱们就有必要进行水平分表了

水平分表其实很好理解,好比一个一千万记录的表,咱们能够根据记录数分红十张一百万的表,第一张就是一到一百万,一次日后…

有时候会遇到这种需求,加入须要查询第五百万条到第八百三十二万条怎么办呢,这时候咱们能够用UNION和UNION ALL来把结果集进行联合

水平分表中的id咱们能够经过主键自增、UUID、雪花算法等来进行求出

最简单的一种hash算法:t_user+id%100(分表数)+1

SQL语句优化

DDL优化

  • 经过禁用索引来提供导入数据性能
  • 关闭惟一校验
  • 修改事务提交方式

DML优化

将多条结构相关的sql语句合并味一条

DQL优化

  • order by优化,多用索引进行排序
  • group by优化,在group by是使用order by null,取消默认排序
  • subQuery嵌套优化,利用嵌套进行优化
  • limit优化(重要) 在分页条件那里尽可能使用一个带索引的字段进行排序或者过滤好比:select * from test id>4000 limit 5