MySQL的最大连接数,如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,当然这建立在机器能支撑的情况下,因为如果连接数越多,介于MySQL会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。
用一下命令查看当前链接数和最大连接数。
# 查看当前链接的线程数
show status like 'thread%';
# 查看最大使用链接数
show status like 'Max_used_connections';
MySQL每打开一个表,都会读入一些数据到table_open_cache缓存中,当MySQL在这个缓存中找不到相应信息时,才会去磁盘上读取。
通过检查峰值时间的状态值Open_tables和Opened_tables,其中open_tables表示当前打开的table总和,即所有connection打开的table总数,opened_tables表示打开过的表的数量总和,只有show global status才能看到它的值。
#查看table_open_cache配置信息
SHOW VARIABLES LIKE 'table_open_cache%';
#查看当前打开的table总和 和 打开过的表的数量总和
SHOW GLOBAL STATUS LIKE 'Open%tables';
比较适合的值:
Open_tables / Opened_tables >= 0.85
Open_tables / table_open_cache <= 0.95
如果对此参数的把握不是很准,有个很保守的设置建议:把MySQL数据库放在生产环境中试运行一段时间,然后把参数的值调整得比Opened_tables的数值大一些,并且保证在比较高负载的极端条件下依然比Opened_tables略大。
增加它可得到更好处理的索引(对所有读和多重写),到你能负担得起那样多。对于内存在4GB左右的服务器该参数可设置为384M或512M。通过检查状态值Key_read_requests和Key_reads,可以知道key_buffer_size设置是否合理。比例key_reads/key_read_requests应该尽可能的低,至少是1:100,1:1000更好。注意:该参数值设置的过大反而会使服务器整体效率降低。
#查看请求索引数和读取索引数状态值
show status like 'Key_read%';
参数说明:
-s,是order的顺序
al 平均锁定时间
ar 平均返回记录时间
at 平均查询时间(默认)
c 计数
l 锁定时间
r 返回记录
t 查询时间
-t,是top n的意思,即为返回前面多少条的数据
-g,后边可以写一个正则匹配模式,大小写不敏感
注意:
Windows下使用mysqldumpslow需要先安装Perl。
然后使用 perl D:\mysql\bin\mysqldumpslow.pl 后接参数
参考一下示例
#返回查询最慢的20个SQL,并写入到slow_top20.txt文件
mysqldumpslow -t 20 /var/lib/mysql/slowquery.log > slow_top20.txt
#返回记录集最多的20个SQL
mysqldumpslow -s r -t 20 /var/lib/mysql/slowquery.log
#得到访问次数最多的20个SQL
mysqldumpslow -s c -t 20 /var/lib/mysql/slowquery.log
#得到按照时间排序的前20条里面含有左连接的查询语句
mysqldumpslow -s t -t 20 -g “left join” /var/lib/mysql/slowquery.log
#得到按照平均锁表时间排序的前20个SQL
mysqldumpslow -s al -t 20 /var/lib/mysql/slowquery.log
查看是否执行索引: EXPLAIN或者DESC后接SQL语句( SQL语句不会真正被执行)
EXPLAIN SELECT * FROM est_client WHERE cle_phone='123';
参数详解
±—±------------±------±------±------------------±--------±--------±------±-----
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±------±------------------±--------±--------±------±-----
下面对各个属性进行了解:
1、id:这是SELECT的查询序列号
2、select_type:select_type就是select的类型,可以有以下几种:
SIMPLE:简单SELECT(不使用UNION或子查询等)
PRIMARY:最外面的SELECT
UNION:UNION中的第二个或后面的SELECT语句
DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
UNION RESULT:UNION的结果。
SUBQUERY:子查询中的第一个SELECT
DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
DERIVED:导出表的SELECT(FROM子句的子查询)
3、table:显示这一行的数据是关于哪张表的
4、type:这列最重要,显示了连接使用了哪种类别,有无使用索引,是使用Explain命令分析性能瓶颈的关键项之一。
结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,得保证查询至少达到range级别,最好能达到ref,否则就可能会出现性能问题。
5、possible_keys:列指出MySQL能使用哪个索引在该表中找到行
6、key:显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL
7、key_len:显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好
8、ref:显示使用哪个列或常数与key一起从表中选择行。
9、rows:显示MySQL认为它执行查询时必须检查的行数。
10、Extra:包含MySQL解决查询的详细信息,也是关键参考项之一。
RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。
LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。
KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。
注意:用于创建表分区的字段必须设置为主键,可以在原主键上新增一个主键做为联合主键
CREATE TABLE `news` (
`id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(50) NULL,
`content` TEXT NULL,
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`, `create_time`)
)
COLLATE='utf8_general_ci'
ENGINE=INNODB
PARTITION BY RANGE (TO_DAYS(create_time))
(
PARTITION p_2016 VALUES LESS THAN (TO_DAYS('2017-01-01')),
PARTITION p_2017 VALUES LESS THAN (TO_DAYS('2018-01-01')),
PARTITION p_2018 VALUES LESS THAN (TO_DAYS('2019-01-01'))
);
ALTER TABLE `news` PARTITION BY RANGE (TO_DAYS(create_time))
(
PARTITION p_2016_2017 VALUES LESS THAN (TO_DAYS('2018-01-01')),
PARTITION p_2018 VALUES LESS THAN (TO_DAYS('2019-01-01'))
);
ALTER TABLE `news` ADD PARTITION (
PARTITION p_2019 VALUES LESS THAN (TO_DAYS('2020-01-01'))
);
ALTER TABLE `news` DROP PARTITION p_2019;
谨慎使用,删除表分区会导致表分区内的数据也被删除,当然也可以巧妙的用做快速删除表分区内全部数据的一种方法。
ALTER TABLE news REORGANIZE PARTITION p_2018 INTO (
PARTITION p_2018_Q1 VALUES LESS THAN (TO_DAYS('2018-04-01')),
PARTITION p_2018_Q2 VALUES LESS THAN (TO_DAYS('2018-07-01')),
PARTITION p_2018_Q3 VALUES LESS THAN (TO_DAYS('2018-10-01')),
PARTITION p_2018_Q4 VALUES LESS THAN (TO_DAYS('2019-01-01'))
);
ALTER TABLE news REORGANIZE PARTITION
p_2018_Q1,p_2018_Q2,p_2018_Q3,p_2018_Q4 INTO
(
PARTITION p_2018_half1 VALUES LESS THAN (TO_DAYS('2018-07-01')),
PARTITION p_2018_half2 VALUES LESS THAN (TO_DAYS('2019-01-01'))
);
SELECT * FROM news PARTITION(p_2017);
SELECT * FROM news PARTITION(p_2018_half1,p_2018_half2);
CREATE TABLE `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`group_id` INT(11) NOT NULL,
`user_name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`, `group_id`)
)
COLLATE='utf8_general_ci'
ENGINE=INNODB
PARTITION BY LIST (group_id)
(
PARTITION p_group_a VALUES IN (1,3,8)
INDEX DIRECTORY = '/var/data/test_db/user'
DATA DIRECTORY = ‘/var/data/test_db/user ',
PARTITION p_group_b VALUES IN (2,4,5),
INDEX DIRECTORY = ‘/var/data/test_db/user '
DATA DIRECTORY = ‘/var/data/test_db/user ',
PARTITION p_group_c VALUES IN (6,7)
INDEX DIRECTORY = ‘/var/data/test_db/user '
DATA DIRECTORY = ‘/var/data/test_db/user ',
);
此方法可以解决一些磁盘空间分配和磁盘IO性能的问题。
本文暂不做介绍
#查看所有进程,查看Command、Time、State和Info,可以分析死锁情况
show processlist;
#结束进程,发现死锁的进程,可以用命令直接杀掉
kill 12041;
#查询是否锁表
show OPEN TABLES where In_use>0;
#正在运行的,包括在锁的和待锁的
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
#查看正在被锁住的
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
#查看等待锁的
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;