MySQL_优化

MySQL优化就是通过合理安排资源,调整系统参数使MySQL运行更快更节省资源。所以,一方面要找出系统瓶颈,提高MySQL的整体性能,另一方面需要合理的结构设计和参数调整以提高用户操作的响应速度,同时,还应该尽可能节省系统资源,以便提供更大负荷的服务。

MySQL数据库优化是多方面的,原则是减少系统瓶颈,减少资源的占用,增加系统的反应速度。例如优化文件系统,提高磁盘IO速度,通过优化操作系统调度策略,提高在高负荷情况下负载能力,优化表结构,索引,查询语句等使查询响应更快。

性能参数

使用show status查看一些性能参数

show status like 'value';

其中value表示参数值,常见:

connections:连接数据库次数
uptime:服务器上线时间
slow_queries:慢查询次数
com_select:查询操作次数
com_update:更新操作次数
com_insert:插入操作次数
com_delete:删除操作次数

查看允许最大连接数:

show variables like 'max_connections';

查询语句分析

通过查询语句的分析,可以知道查询语句的执行情况,找出查询语句执行的瓶颈,从而优化。MySQL提供了explain和describe语句用来分析。

explain [extended] select...
describe select ...

使用explain关键字可以知道MySQL是如何处理SQL语句的,还会告诉我们索引主键是如何被利用的,数据表是如何被搜索或排序的等等

explain语句各行解释:

select_type:所使用的查询类型,可能的取值有simpleprimaryunion,subquery等
table:数据表的名称,按照读取先后顺序
type:本数据表和其他表之间的关系,可能值有system,const,eq_ref,ref,range,indexall
possible_key:查询时可选用的索引
key:实际选用索引
key_len:索引按字节计算的长度,数值越小越快
ref:关联关系中另一个数据表的列的名字
rows:预计执行查询时从数据表中查询出的行数
extra:与关联查询有关的信息

优化查询

使用查询缓存

大多数MySQL服务器都开启了查询缓存,这是提高性能最有效的方法之一,这是被MySQL引擎处理的。当有很多相同的查询被执行多次之后,这些查询结果就会被放在缓存中,这样后续相同的查询就不需要进行操作,直接访问缓存就可以了。

这里最主要的问题是,这个事情很容易被忽略,某些查询语句会让MySQL不使用缓存

select username from user where signup_date>=curdate();

MySQL的查询缓存对curdate这个函数不起作用。所以,像now和rand或者其他诸如此类的SQL函数都不会开启查询缓存,因为这些函数的返回是不定易变的。所以需要用一个变量来代替MySQL的函数,从而开启缓存。

当只要一行数据时使用limit 1

加上limit 1可以增加性能。MySQL数据库引擎会查找到一条数据后停止搜索。

避免使用select *

从数据库中读出越多的数据,那么查询就会变得越慢。并且,如果我们的数据库服务器和web服务器是两台独立的服务器的话,这还会增加网络传输的负载。所以应该养成需要什么就取什么的好习惯。

永远为每张表设置一个id主键

为数据库里的每张表都设置一个id作为主键,而且最好是int类型(unsigned)。并设置自动增加auto_increment。即使是user表中有一个叫“email”的字段,也别让它成为主键。使用VARCHAR类型当主键会使性能下降。

尽可能的不要赋值为null

在MySQL中对于int类型,empty为0,而null是空值。而在Oracle中null和empty的字符串都是一样的。null也需要占用存储空间,并且会使我们的程序判断时更加复杂。

固定长度的表会更快

如果表中的所有字段都是固定长度的,整个表会被认为是static或fixed-length。例如,表中没有VARCHAR,text,blob。只要包含了其中一个这些字段,那么这个表就不是固定长度了,MySQL引擎会用另一种方法来处理。固定长度的表会提高性能,因为搜索得会更快一些,很容易计算下一个数据偏移量,所以读取自然会很快。而如果字段不是定长了,每一次要找下一条,需要程序找到主键。并且,固定长度的表更容易被缓存和重建。不过,唯一副作用是,会浪费空间,因为定长字段无论是否被使用,都是要分配固定的空间。另外在取出值时需要使用trim去除空格。

越小的列越快

对于大多数数据库引擎来说,硬盘操作可能是最大的瓶颈。所以,把我们的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问。如果我们不需要记录时间,使用date要比datetime好的多。

选择合适的存储引擎

MyISAM适合一些需要大量查询的应用,但是对于大量写操作的支持不是很好,甚至一个update语句就会进行锁表操作,另外MyISAM对于select count(*)这类计算是非常快的。

InnoDB是一个非常复杂的存储引擎,对于一些小的应用,会比MyISAM慢。支持行锁,在写操作比较多时,会更优秀,还支持更多高级应用,如事务。

为搜素字段创建索引

索引不一定就是给主键或是唯一的字段,如果在表中,有某个字段经常用来做搜索,需要在该列上建立索引。

注意:组合索引的生效原则是,从前往后依次使用生效,如果中间某个索引没有使用,那么断点前面的索引部分起作用,断点后面的索引没有起作用,造成断点的原因:
前边的任意一个索引没有参与查询,后边的全部不生效
前边的任意一个索引参与的是范围查询,后边的不生效
断点跟索引字段在SQL语句中的位置前后无关,只与是否存在有关

例如,在a,b,c三列上添加组合索引后,会出现以下问题:

-- 3个索引都用到且发挥作用
select * from table where a=3 and b=5 and c=4;
-- 组合索引在SQL的位置先后无关
select * from table where b=5 and c=4 and a=3;
-- a用到索引,b没有yong,所以c没有用到
select * from table where a=3 and c=4;
-- a用到,b用到,但b为范围搜索,所以c没用到
select * from table where a=3 and b>5 and c=4;
-- a没有用到,所以bc都没有用到
select * from table where b=5 and c=4;

在join表的时候使用相同类型的列,并将其索引

如果程序中有很多join查询,应该保证两个表中的join字段被建立过索引。这样MySQL内部会启动优化join的SQL语句机制。注意这些被用来join的字段应该是相同类型的。

优化数据库结构

合理的数据库结构不仅可以占用更小的磁盘空间,而且能够使查询速度更快。数据库结构的设计,需要考虑数据冗余,查询和更新的速度,字段的数据类型是否合理等内容。

将字段很多的表分解成多个表

对于字段较多的表,如果某些字段的使用频率比较低,可以将这些字段分离出来构成新的表,因为当一个表的数据量很大时,会由于使用频率低的字段存在而变慢。

增加中间表

对于经常需要联合查询的表,可以增加中间表来提高查询效率。通过建立中间表,将经常联合查询的数据插入中间表,然后将原来联合查询改为中间表查询,提高效率。

增加冗余字段

设计数据库表时应尽量遵守范式理论的规约,尽可能减少冗余字段,但是,合理的加入冗余字段可以提高查询速度,比如通过添加冗余字段减少联合查询。

优化插入记录的速度

插入记录时,影响插入速度的主要是索引,唯一性校验,一次插入记录条数等,可分别进行优化。
对于MyISAM的表,常见优化方法:

禁用索引
对于非空表,插入数据时,数据库会根据索引对插入的记录建立新的索引,插入大量数据时,建立索引会降低插入记录的速度,所以可以在插入记录前禁用索引,插入完毕后再开启

alter table tab_name disable keys;
alter table tab_name enable keys;

对空表批量插入不需要此操作

禁用唯一性校验
插入记录时,MySQL会对插入的记录进行唯一性校验,降低插入速度,所以可在插入前禁用,插入完毕后再开启

set unique_checks=0;
set unique_checks=1;

使用批量插入

insert into tab values(),(),()...

使用load data infile批量导入

对于InnoDB的表,常见优化
禁用唯一性校验
禁用外键检查

set foreign_key_checks=0;
set foreign_key_checks=1;

禁用自动提交

set autocommit=0;
set autocommit=1;

分析表,检查表,优化表

analyze [local|no_write_binlog] table tab_name[,tab_name...]

分析表的过程中,数据库自动对表加只读锁

check table tab_name[,tab_name...] [option]
option={quick|fast|medium|extended|changed}

检查表和视图是否存在错误,option只对MyISAM有效

optimize [local|no_write_binlog] table tab_name[,tab_name...]

优化表中的VARCHAR,blob,text类型的字段,可以消除删除或更新造成的文件碎片,加只读锁

优化MySQL服务器

优化硬件

配置较大的内存,配置高速磁盘系统,配置多处理器

服务参数优化

修改my.ini配置文件参数

发布了359 篇原创文章 · 获赞 26 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Chill_Lyn/article/details/104179553