MySql优化相关总结

MySQL架构mysql

 

 


查询执行流程
查询执行的流程是怎样的:算法

链接
1.1客户端发起一条Query请求,监听客户端的‘链接管理模块’接收请求
1.2将请求转发到‘链接进/线程模块’
1.3调用‘用户模块’来进行受权检查
1.4经过检查后,‘链接进/线程模块’从‘线程链接池’中取出空闲的被缓存的链接线程和客户端请求对接,若是失败则建立一个新的链接请求。
处理
2.1先查询缓存,检查Query语句是否彻底匹配,
2.2查询缓存失败则转交给‘命令解析器’
2.3再转交给对应的模块处理
2.4若是是SELECT查询还会经由‘查询优化器’作大量的优化,生成执行计划
2.5模块收到请求后,经过‘访问控制模块’检查所链接的用户是否有访问目标表和目标字段的权限
2.6有则调用‘表管理模块’,先是查看table cache中是否存在,有则直接对应的表和获取锁,不然从新打开表文件
2.8根据表的meta数据,获取表的存储引擎类型等信息,经过接口调用对应的存储引擎处理
2.9上述过程当中产生数据变化的时候,若打开日志功能,则会记录到相应二进制日志文件中
结果
3.1Query请求完成后,将结果集返回给‘链接进/线程模块’
3.2返回的也能够是相应的状态标识,如成功或失败等
3.3‘链接进/线程模块’进行后续的清理工做,并继续等待请求或断开与客户端的链接
什么是优化
合理安排资源、调整系统参数使MySQL运行更快、更节省资源。
优化是多方面的,包括查询、表设计、服务器等。
原则:减小系统瓶颈,减小资源占用,增长系统的反应速度。
查询优化
在优化MySQL时,一般须要库进行分析。常见的分析手段有慢查询日志,EXPLAIN 分析查询,经过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。sql

慢查询日志
慢查询日志开启
在配置文件my.cnf或my.ini中在[mysqld]一行下面加入两个配置参数
log-slow-queries=/data/mysqldata/slow-query.log
long_query_time=5
注:log-slow-queries参数为慢查询日志存放的位置,通常这个目录要有mysql的运行账号的可写权限,通常都将这个目录设置为mysql的数据存放目录;
long_query_time=5中的5表示查询超过五秒才记录;
还能够在my.cnf或者my.ini中添加log-queries-not-using-indexes参数,表示记录下没有使用索引的查询。
慢查询分析
咱们能够经过打开log文件查看得知哪些SQL执行效率低下
从日志中,能够发现查询时间超过5 秒的SQL,而小于5秒的没有出如今此日志中。
若是慢查询日志中记录内容不少,可使用mysqldumpslow工具(MySQL客户端安装自带)来对慢查询日志进行分类汇总。mysqldumpslow对日志文件进行了分类汇总,显示汇总后摘要结果。
进入log的存放目录,运行
[root@mysql_data]#mysqldumpslow slow-query.log
Reading mysql slow query log from slow-query.log
Count: 2 Time=11.00s (22s) Lock=0.00s (0s) Rows=1.0 (2), root[root]@mysql
select count(N) from t_user;数据库

mysqldumpslow命令
/path/mysqldumpslow -s c -t 10 /database/mysql/slow-query.log
这会输出记录次数最多的10条SQL语句,其中:缓存

-s, 是表示按照何种方式排序,c、t、l、r分别是按照记录次数、时间、查询时间、返回的记录数来排序,ac、at、al、ar,表示相应的倒叙
-t, 是top n的意思,即为返回前面多少条的数据;
-g, 后边能够写一个正则匹配模式,大小写不敏感的;安全

例如:
/path/mysqldumpslow -s r -t 10 /database/mysql/slow-log
获得返回记录集最多的10个查询。
/path/mysqldumpslow -s t -t 10 -g “left join” /database/mysql/slow-log
获得按照时间排序的前10条里面含有左链接的查询语句。服务器

使用mysqldumpslow命令能够很是明确的获得各类咱们须要的查询语句,对MySQL查询语句的监控、分析、优化是MySQL优化很是重要的一步。开启慢查询日志后,因为日志记录操做,在必定程度上会占用CPU资源影响mysql的性能,可是能够阶段性开启来定位性能瓶颈。网络

EXPLAIN
在MySQL中可使用EXPLAIN查看SQL执行计划,用法:EXPLAIN SELECT * FROM products
5.2.1.id
SELECT识别符。这是SELECT查询序列号。这个不重要。
5.2.2.select_type
表示SELECT语句的类型。
例如:
一、SIMPLE
表示简单查询,其中不包含链接查询和子查询。
二、PRIMARY
表示主查询,或者是最外面的查询语句。
三、UNION
表示链接查询的第2个或后面的查询语句。
5.2.3.table
表示查询的表。
5.2.4.type
表示表的链接类型。
如下的链接类型的顺序是从最佳类型到最差类型:
一、system
表仅有一行,这是const类型的特列,平时不会出现,这个也能够忽略不计。
二、const
数据表最多只有一个匹配行,由于只匹配一行数据,因此很快,经常使用于
三、eq_ref
mysql手册是这样说的:“对于每一个来自于前面的表的行组合,从该表中读取一行。这多是最好的联接类型,除了const类型。它用在一个索引的全部部分被联接使用而且索引是UNIQUE或PRIMARY KEY”。eq_ref能够用于使用=比较带索引的列。
四、ref
查询条件索引既不是UNIQUE也不是PRIMARY KEY的状况。ref可用于=或<或>操做符的带索引的列。
五、ref_or_null
该联接类型如同ref,可是添加了MySQL能够专门搜索包含NULL值的行。在解决子查询中常用该联接类型的优化。
上面这五种状况都是很理想的索引使用状况。
六、index_merge
该联接类型表示使用了索引合并优化方法。在这种状况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。
七、unique_subquery
该类型替换了下面形式的IN子查询的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一个索引查找函数,能够彻底替换子查询,效率更高。
八、index_subquery
该联接类型相似于unique_subquery。能够替换IN子查询,但只适合下列形式的子查询中的非惟一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
九、range
只检索给定范围的行,使用一个索引来选择行。
十、index
该联接类型与ALL相同,除了只有索引树被扫描。这一般比ALL快,由于索引文件一般比数据文件小。
十一、ALL
对于每一个来自于先前的表的行组合,进行完整的表扫描。(性能最差)
5.2.5.possible_keys
指出MySQL能使用哪一个索引在该表中找到行。
若是该列为NULL,说明没有使用索引,能够对该列建立索引来提升性能。
5.2.6.key
显示MySQL实际决定使用的键(索引)。若是没有选择索引,键是NULL。
5.2.7.key_len
显示MySQL决定使用的键长度。若是键是NULL,则长度为NULL。
注意:key_len是肯定了MySQL将实际使用的索引长度。
5.2.8.ref
显示使用哪一个列或常数与key一块儿从表中选择行。
5.2.9.rows
显示MySQL认为它执行查询时必须检查的行数。
5.2.10.Extra
该列包含MySQL解决查询的详细信息
Distinct:MySQL发现第1个匹配行后,中止为当前的行组合搜索更多的行。
Not exists:MySQL可以对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,再也不为前面的的行组合在该表内检查更多的行。
range checked for each record (index map: #):MySQL没有发现好的可使用的索引,但发现若是来自前面的表的列值已知,可能部分索引可使用。
Using filesort:MySQL须要额外的一次传递,以找出如何按排序顺序检索行。
Using index:从只使用索引树中的信息而不须要进一步搜索读取实际的行来检索表中的列信息。
Using temporary:为了解决查询,MySQL须要建立一个临时表来容纳结果。
Using where:WHERE 子句用于限制哪个行匹配下一个表或发送到客户。
Using sort_union(…), Using union(…), Using intersect(…):这些函数说明如何为index_merge联接类型合并索引扫描。
Using index for group-by:相似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,能够用来查 询GROUP BY或DISTINCT查询的全部列,而不要额外搜索硬盘访问实际的表。数据结构

索引使用
6.1.1.MySQL索引
6.1.1.1.B-Tree索引
通常来讲,MySQL中的B-Tree索引的物理文件大多都是以二叉树的结构来存储的,也就是全部实际须要的数据都存放于树的叶子节点,并且到任何一个叶子节点的最短路径的长度都是彻底相同的。
6.1.1.2.R-Tree索引
RTREE在mysql不多使用,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。相对于BTREE,RTREE的优点在于范围查找.
6.1.1.3.Hash索引
Hash索引在MySQL中使用的并非不少,目前主要是Memory存储引擎使用,并且在Memory存储引擎中将Hash索引做为默认的索引类型。所谓Hash索引,实际上就是经过必定的Hash算法,将须要索引的键值进行Hash运算,而后将获得的Hash值存入一个Hash表中。而后每次须要检索的时候,都会将检索条件进行相同算法的Hash运算,而后再和Hash表中的Hash值进行比较并得出相应的信息。
Hash索引仅仅只能知足“=”,“IN”和“<=>”查询,不能使用范围查询;
Hash索引没法被利用来避免数据的排序操做;
Hash索引不能利用部分索引键查询;
Hash索引在任什么时候候都不能避免表扫面;
Hash索引遇到大量Hash值相等的状况后性能并不必定就会比B-Tree索引高;
6.1.1.4.Full-text索引
Full-text索引也就是咱们常说的全文索引,目前在MySQL中仅有MyISAM存储引擎支持,并且也并非全部的数据类型都支持全文索引。目前来讲,仅有CHAR,VARCHAR和TEXT这三种数据类型的列能够建Full-text索引。
6.1.2.建立索引
是否须要建立索引,几点原则:架构

较频繁的做为查询条件的字段应该建立索引;
惟一性太差的字段不适合单首创建索引,即便频繁做为查询条件;
更新很是频繁的字段不适合建立索引;
不会出如今WHERE子句中的字段不应建立索引;
索引可以极大的提升数据检索效率,也可以改善排序分组操做的性能,可是咱们不能忽略的一个问题就是索引是彻底独立于基础数据以外的一部分数据,更新数据会带来的IO量和调整索引所致的计算量的资源消耗。
6.1.3.使用索引
6.1.3.1.使用联合索引的查询
MySQL能够为多个字段建立索引,一个索引能够包括16个字段。对于联合索引,只有查询条件中使用了这些字段中第一个字段时,索引才会生效。
6.1.3.2.使用OR关键字的查询
查询语句的查询条件中只有OR关键字,且OR先后的两个条件中的列都是索引时,索引才会生效,不然,索引不生效。
存储优化
存储数据时,影响存储速度的主要是索引、惟一性校验、一次存储的数据条数等。

存储数据的优化,不一样的存储引擎优化手段不同,在MySQL中经常使用的存储引擎有,MyISAM和InnoDB,二者的区别:

7.1.存储引擎介绍
7.1.1.MyISAM存储引擎
MyISAM存储引擎是一种非事务性的引擎,提供高速存储和检索,以及全文搜索能力,适合数据仓库等查询频繁的应用。

每个表都被存放为三个以表名命名的物理文件。有存放表结构定义信息的.frm文件,还有存放了表的数据.MYD文件和存放索引数据的.MYI文件。

7.1.2.Innodb 存储引擎
Innodb 存储引擎是事务安全的, 所以若是须要一个事务安全的存储引擎,建议使用它。若是你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑应该使用InnoDB表。

InnoDB 给 MySQL 提供了具备事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。InnoDB 提供了行锁(locking on row level),提供与 Oracle 类型一致的不加锁读取(non-locking read in SELECTs)。这些特性均提升了多用户并发操做的性能表现。

在InnoDB表中不须要扩大锁定(lock escalation),由于 InnoDB 的列锁定(row level locks)适宜很是小的空间。InnoDB 是 MySQL 上提供外键约束(FOREIGN KEY constraints)的表引擎。

InnoDB 的设计目标是处理大容量数据库系统,它的 CPU 利用率是其它基于磁盘的关系数据库引擎所不能比的。在技术上,InnoDB 是一套放在 MySQL 后台的完整数据库系统,InnoDB 在主内存中创建其专用的缓冲池用于高速缓冲数据和索引。

InnoDB 把数据和索引存放在表空间里,可能包含多个文件,这与MyISAM不同。InnoDB 表的大小只受限于操做系统的文件大小,通常为 2 GB。InnoDB全部的表都保存在同一个数据文件 ibdata1 中(也多是多个文件,或者是独立的表空间文件),相对来讲比较很差备份。备份的方案能够是拷贝数据文件、备份 binlog,或者用 mysqldump。

7.2.MyISAM和Innodb的区别
InnoDB和MyISAM是许多人在使用MySQL时最经常使用的两个表类型,这两个表类型各有优劣,视具体应用而定。基本的差异为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,可是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能。

7.2.1.具体实现的差异:

MyISAM是非事务安全型的,而InnoDB是事务安全型的。
MyISAM锁的粒度是表级,而InnoDB支持行级锁定。
MyISAM支持全文类型索引,而InnoDB不支持全文索引。
MyISAM相对简单,因此在效率上要优于InnoDB,小型应用能够考虑使用MyISAM。
MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去很多的麻烦。
InnoDB表比MyISAM表更安全,能够在保证数据不会丢失的状况下,切换非事务表到事务表(alter table tablename type=innodb)。
7.2.2.应用场景

MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。若是应用中须要执行大量的SELECT查询,那么MyISAM是更好的选择。
InnoDB用于事务处理应用程序,具备众多特性,包括ACID事务支持。若是应用中须要执行大量的INSERT或UPDATE操做,则应该使用InnoDB,这样能够提升多用户并发操做的性能。
7.3.MyISAM存储优化
7.3.1.禁用索引
对于非空表,插入记录时,MySQL会根据表的索引对插入的记录创建索引。若是插入大量数据,创建索引会下降插入数据速度。
为了解决这个问题,能够在批量插入数据以前禁用索引,数据插入完成后再开启索引。
禁用索引的语句:
ALTER TABLE table_name DISABLE KEYS
开启索引语句:
ALTER TABLE table_name ENABLE KEYS
对于空表批量插入数据,则不须要进行操做,由于MyISAM引擎的表是在导入数据后才创建索引。
7.3.2.禁用惟一性检查
惟一性校验会下降插入记录的速度,能够在插入记录以前禁用惟一性检查,插入数据完成后再开启。
禁用惟一性检查的语句:SET UNIQUE_CHECKS = 0;
开启惟一性检查的语句:SET UNIQUE_CHECKS = 1;
7.3.3.批量插入数据
插入数据时,可使用一条INSERT语句插入一条数据,也能够插入多条数据。
7.3.4.使用LOAD DATA INFILE
当须要批量导入数据时,使用LOAD DATA INFILE语句比INSERT语句插入速度快不少。
7.4.InnoDB
7.4.1.禁用惟一性检查
用法和MyISAM同样。
7.4.2.禁用外键检查
插入数据以前执行禁止对外键的检查,数据插入完成后再恢复,能够提供插入速度。
禁用:SET foreign_key_checks = 0;
开启:SET foreign_key_checks = 1;
7.4.3.禁止自动提交
插入数据以前执行禁止事务的自动提交,数据插入完成后再恢复,能够提升插入速度。
禁用:SET autocommit = 0;
开启:SET autocommit = 1;
数据库结构优化
8.1.优化表结构

尽可能将表字段定义为NOT NULL约束,这时因为在MySQL中含有空值的列很难进行查询优化,NULL值会使索引以及索引的统计信息变得很复杂。
对于只包含特定类型的字段,可使用enum、set 等符合数据类型。
数值型字段的比较比字符串的比较效率高得多,字段类型尽可能使用最小、最简单的数据类型。例如P地址可使用int类型。
尽可能使用TINYINT、SMALLINT、MEDIUM_INT做为整数类型而非INT,若是非负则加上UNSIGNED
VARCHAR的长度只分配真正须要的空间
尽可能使用TIMESTAMP而非DATETIME,
单表不要有太多字段,建议在20之内
合理的加入冗余字段能够提升查询速度。
8.2.表拆分
8.2.1.垂直拆分
垂直拆分按照字段进行拆分,其实就是把组成一行的多个列分开放到不一样的表中,这些表具备不一样的结构,拆分后的表具备更少的列。例如用户表中的一些字段可能常常访问,能够把这些字段放进一张表里。另一些不常用的信息就能够放进另一张表里。

插入的时候使用事务,也能够保证两表的数据一致。缺点也很明显,因为拆分出来的两张表存在一对一的关系,须要使用冗余字段,并且须要join操做,咱们在使用的时候能够分别取两次,这样的来讲既能够避免join操做,又能够提升效率。

8.2.2.水平拆分
水平拆分按照行进行拆分,常见的就是分库分表。以用户表为例,能够取用户ID,而后对ID取10的余数,将用户均匀的分配进这 0-9这10个表中。查找的时候也按照这种规则,又快又方便。

有些表业务关联比较强,那么可使用按时间划分的。例如天天的数据量很大,须要天天新建一张表。这种业务类型就是须要高速插入,可是对于查询的效率不太关心。表越大,插入数据所须要索引维护的时间也就越长。
8.3.分区
使用分区是大数据处理后的产物。好比系统用户的注册推广等等,会产生海量的日志,固然也能够按照时间水平拆分,创建多张表。但在实际操做中,容易发生忘记切换表致使数据错误。
分区适用于例如日志记录,查询少。通常用于后台的数据报表分析。对于这些数据汇总需求,须要不少日志表去作数据聚合,咱们可以容忍1s到2s的延迟,只要数据准确可以知足需求就能够。
MySQL主要支持4种模式的分区:range分区、list预约义列表分区,hash 分区,key键值分区。
8.4.读写分离
大型网站会有大量的并发访问,若是仍是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库链接操做,数据库必然会崩溃,数据丢失的话,后果更是不堪设想。这时候,咱们须要考虑如何减小数据库的联接。
咱们发现通常状况对数据库而言都是“读多写少”,也就说对数据库读取数据的压力比较大,这样分析能够采用数据库集群的方案。其中一个是主库,负责写入数据,咱们称为写库;其它都是从库,负责读取数据,咱们称为读库。这样能够缓解一台服务器的访问压力
8.5.数据库集群
若是访问量很是大,虽然使用读写分离可以缓解压力,可是一旦写操做一台服务器都不能承受了,这个时候咱们就须要考虑使用多台服务器实现写操做。
例如可使用MyCat搭建MySql集群,对ID求3的余数,这样能够把数据分别存放到3台不一样的服务器上,由MyCat负责维护集群节点的使用。

硬件优化
是服务器的硬件性能直接决定着MySQL数据库的性能,硬件的性能瓶颈,直接决定MySQL数据库的运行速度和效率。

能够从如下几个方面考虑:
一、配置较大的内存。足够大的内存,是提升MySQL数据库性能的方法之一。内存的IO比硬盘快的多,能够增长系统的缓冲区容量,使数据在内存停留的时间更长,以减小磁盘的IO。

二、磁盘I/O相关

使用SSD或者PCIe SSD设备,至少得到数百倍甚至万倍的IOPS提高;购置阵列卡同时配备CACHE及BBU模块,可明显提高IOPS尽量选用RAID-10,而非RAID-5使用机械盘的话,尽量选择高转速的,例如选用15000RPM,而不是7200RPM的盘三、配置CPU相关   在服务器的BIOS设置中,可调整下面的几个配置:选择Performance Per Watt Optimized(DAPC)模式,发挥CPU最大性能;关闭C1E和C States等选项,提高CPU效率;Memory Frequency(内存频率)选择Maximum Performance;MySQL缓存为了提升查询速度,咱们能够经过不一样的方式去缓存咱们的结果从而提升响应效率。当咱们的数据库打开了Query Cache(简称QC)功能后,数据库在执行SELECT语句时,会将其结果放到QC中,当下一次处理一样的SELECT请求时,数据库就会从QC取得结果,而不须要去数据表中查询。若是缓存命中率很是高的话,有测试代表在极端状况下能够提升效率238%。但一个缓存机制是否有效,效果如何,倒是一个须要好好思考的问题。Query Cache有以下规则,若是数据表被更改,那么和这个数据表相关的所有Cache所有都会无效,并删除之。这里“数据表更改”包括: INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE等。举个例子,若是数据表item访问频繁,那么意味着它的不少数据会被QC缓存起来,可是每一次item数据表的更新,不管更新是否是影响到了cache 的数据,都会将所有和item表相关的cache清除。若是你的数据表更新频繁的话,那么Query Cache将会成为系统的负担。有实验代表,糟糕时,QC会下降系统13%的处理能力。10.1.1.全局缓存数据库属于IO密集型的应用程序,其主职责就是数据的管理及存储工做。而咱们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个 IO是在毫秒级别,两者相差3个数量级。因此,要优化数据库,首先第一步须要优化的就是IO,尽量将磁盘IO转化为内存IO,也就是使用缓存启动MySQL时就要分配而且老是存在的全局缓存,能够在MySQL的my.conf或者my.ini文件的[mysqld]组中配置。目前有:key_buffer_size(默认值:402653184,即384M)、innodb_buffer_pool_size(默认值:134217728即:128M)、innodb_additional_mem_pool_size(默认值:8388608即:8M)、innodb_log_buffer_size(默认值:8388608即:8M)、query_cache_size(默认值:33554432即:32M)等五个。总共:560M.10.1.1.1.key_buffer_sizekey_buffer_size是用于索引块的缓冲区大小,增长它可获得更好处理的索引(对全部读和多重写),对MyISAM表性能影响最大的一个参数。若是你使它太大,系统将开始换页而且真的变慢了。严格说是它决定了数据库索引处理的速度,尤为是索引读的速度。对于内存在4GB左右的服务器该参数可设置为256M或384M.10.1.1.2.innodb_buffer_pool_sizeinnodb_buffer_pool_size:主要针对InnoDB表性能影响最大的一个参数。功能与Key_buffer_size同样。InnoDB占用的内存,除innodb_buffer_pool_size用于存储页面缓存数据外,另外正常状况下还有大约8%的开销,主要用在每一个缓存页帧的描述、adaptive hash等数据结构,若是不是安全关闭,启动时还要恢复的话,还要另开大约12%的内存用于恢复,二者相加就有差很少21%的开销。10.1.1.3.innodb_additional_mem_pool_sizeinnodb_additional_mem_pool_size 设置了InnoDB存储引擎用来存放数据字典信息以及一些内部数据结构的内存空间大小,因此当咱们一个MySQL Instance中的数据库对象很是多的时候,是须要适当调整该参数的大小以确保全部数据都能存放在内存中提升访问效率的。10.1.1.4.innodb_log_buffer_sizeinnodb_log_buffer_size这是InnoDB存储引擎的事务日志所使用的缓冲区。相似于Binlog BufferInnoDB在写事务日志的时候,为了提升性能,也是先将信息写入Innofb Log Buffer中,当知足innodb_flush_log_trx_commit参数所设置的相应条件(或者日志缓冲区写满)以后,才会将日志写到文件 (或者同步到磁盘)中。能够经过innodb_log_buffer_size 参数设置其可使用的最大内存空间。InnoDB 将日志写入日志磁盘文件前的缓冲大小。理想值为 1M 至 8M。大的日志缓冲容许事务运行时不须要将日志保存入磁盘而只到事务被提交(commit)。 所以,若是有大的事务处理,设置大的日志缓冲能够减小磁盘I/O。 这个参数实际上还和另外的flush参数相关。通常来讲不建议超过32MB10.1.1.5.query_cache_sizequery_cache_size: 主要用来缓存MySQL中的ResultSet,也就是一条SQL语句执行的结果集,因此仅仅只能针对select语句。当咱们打开了 Query Cache功能,MySQL在接受到一条select语句的请求后,若是该语句知足Query Cache的要求,MySQL会直接根据预先设定好的HASH算法将接受到的select语句以字符串方式进行hash,而后到Query Cache中直接查找是否已经缓存。若是已经在缓存中,该select请求就会直接将数据返回,从而省略了后面全部的步骤(如SQL语句的解析,优化器优化以及向存储引擎请求数据等),极大的提升性能。固然,Query Cache也有一个致命的缺陷,那就是当某个表的数据有任何任何变化,都会致使全部引用了该表的select语句在Query Cache中的缓存数据失效。因此,当咱们的数据变化很是频繁的状况下,使用Query Cache可能会得不偿失10.1.2.局部缓存除了全局缓冲,MySql还会为每一个链接发放链接缓冲。个链接到MySQL服务器的线程都须要有本身的缓冲。大概须要马上分配256K,甚至在线程空闲时,它们使用默认的线程堆栈,网络缓存等。事务开始以后,则须要增长更多的空间。运行较小的查询可能仅给指定的线程增长少许的内存消耗,然而若是对数据表作复杂的操做例如扫描、排序或者须要临时表,则需分配大约read_buffer_size,sort_buffer_size,read_rnd_buffer_size,tmp_table_size 大小的内存空间. 不过它们只是在须要的时候才分配,而且在那些操做作完以后就释放了。10.1.2.1.read_buffer_sizeread_buffer_size是MySql读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySql会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。若是对表的顺序扫描请求很是频繁,而且你认为频繁扫描进行得太慢,能够经过增长该变量值以及内存缓冲区大小提升其性能.10.1.2.2.sort_buffer_sizesort_buffer_size是MySql执行排序使用的缓冲大小。若是想要增长ORDER BY的速度,首先看是否可让MySQL使用索引而不是额外的排序阶段。若是不能,能够尝试增长sort_buffer_size变量的大小10.1.2.3.read_rnd_buffer_sizeread_rnd_buffer_size 是MySql的随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySql会首先扫描一遍该缓冲,以免磁盘搜索,提升查询速度,若是须要排序大量数据,可适当调高该值。但MySql会为每一个客户链接发放该缓冲空间,因此应尽可能适当设置该值,以免内存开销过大。10.1.2.4.tmp_table_sizetmp_table_size是MySql的heap (堆积)表缓冲大小。全部联合在一个DML指令内完成,而且大多数联合甚至能够不用临时表便可以完成。大多数临时表是基于内存的(HEAP)表。具备大的记录长度的临时表 (全部列的长度的和)或包含BLOB列的表存储在硬盘上。若是某个内部heap(堆积)表大小超过tmp_table_size,MySQL能够根据须要自动将内存中的heap表改成基于硬盘的MyISAM表。还能够经过设置tmp_table_size选项来增长临时表的大小。也就是说,若是调高该值,MySql同时将增长heap表的大小,可达到提升联接查询速度的效果。10.1.2.5.record_buffer:record_buffer每一个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。若是你作不少顺序扫描,你可能想要增长该值。10.1.3.其它缓存10.1.3.1.table_cacheTABLE_CACHE(5.1.3及之后版本又名TABLE_OPEN_CACHE),table_cache指定表高速缓存的大小。每当MySQL访问一个表时,若是在表缓冲区中还有空间,该表就被打开并放入其中,这样能够更快地访问表内容。不能盲目地把table_cache设置成很大的值。若是设置得过高,可能会形成文件描述符不足,从而形成性能不稳定或者链接失败。4.2.3.2 thread_cache_size (服务器线程缓存)默认的thread_cache_size=8,,这个值表示能够从新利用保存在缓存中线程的数量,当断开链接时若是缓存中还有空间,那么客户端的线程将被放到缓存中,若是线程从新被请求,那么请求将从缓存中读取,若是缓存中是空的或者是新的请求,那么这个线程将被从新建立,若是有不少新的线程,增长这个值能够改善系统性能.经过比较 Connections 和 Threads_created 状态的变量,能够看到这个变量的做用。11.MySQL服务器参数经过优化MySQL的参数能够提升资源利用率,从而达到提升MySQL服务器性能的目的。MySQL的配置参数都在my.conf或者my.ini文件的[mysqld]组中,经常使用的参数以下:11.1.back_logback_log值指出在MySQL暂时中止回答新请求以前的短期内多少个请求能够被存在堆栈中(每一个链接256kb,占用:125M)。也就是说,若是MySql的链接数据达到max_connections时,新来的请求将会被存在堆栈中,以等待某一链接释放资源,该堆栈的数量即back_log,若是等待链接的数量超过back_log,将不被授予链接资源。11.2.wait_timeout当MySQL链接闲置超过必定时间后将会被强行关闭。MySQL默认的wait-timeout值为8个小时。设置这个值是很是有意义的,好比你的网站有大量的MySQL连接请求(每一个MySQL链接都是要内存资源开销的),因为你的程序的缘由有大量的链接请求空闲啥事也不干,白白占用内存资源,或者致使MySQL超过最大链接数历来没法新建链接致使“Too many connections”的错误。在设置以前你能够查看一下你的MYSQL的状态(可用showprocesslist),若是常常发现MYSQL中有大量的Sleep进程,则须要 修改wait-timeout值了。11.3.max_connectionsmax_connections是指MySql的最大链接数,若是服务器的并发链接请求量比较大,建议调高此值,以增长并行链接数量,固然这创建在机器能支撑的状况下,由于若是链接数越多,介于MySql会为每一个链接提供链接缓冲区,就会开销越多的内存,因此要适当调整该值,不能盲目提升设值。MySQL服务器容许的最大链接数1638411.4.max_user_connectionsmax_user_connections是指每一个数据库用户的最大链接针对某一个帐号的全部客户端并行链接到MYSQL服务的最大并行链接数。简单说是指同一个帐号可以同时链接到mysql服务的最大链接数。设置为0表示不限制。11.5.thread_concurrencythread_concurrency的值的正确与否, 对mysql的性能影响很大, 在多个cpu(或多核)的状况下,错误设置了thread_concurrency的值, 会致使mysql不能充分利用多cpu(或多核), 出现同一时刻只能一个cpu(或核)在工做的状况。thread_concurrency应设为CPU核数的2倍。11.6.skip-name-resolveskip-name-resolve:禁止MySQL对外部链接进行DNS解析,使用这一选项能够消除MySQL进行DNS解析的时间。但须要注意,若是开启该选项,则全部远程主机链接受权都要使用IP地址方式,不然MySQL将没法正常处理链接请求!11.7.default-storage-enginedefault-storage-engine= InnoDB(设置InnoDB类型,另外还能够设置MyISAM类型)设置建立数据库及表默认存储类型————————————————原文连接:https://blog.csdn.net/qq_36541478/article/details/84206512

相关文章
相关标签/搜索