test

简介

show status like 'value'
  • connections:连接mysql服务器的次数
  • uptime:服务器上线时间
  • slow_queries:慢查询次数
  • com_select|insert|update|delete:各项操作次数

优化查询

分析查询语句

image-20210524121134386

CREATE TABLE people(
    id bigint auto_increment primary key,
    zipcode char(32) not null default '',
    address varchar(128) not null default '',
    lastname char(64) not null default '',
    firstname char(64) not null default '',
    birthdate char(10) not null default ''
);

CREATE TABLE people_car(
    people_id bigint,
    plate_number varchar(16) not null default '',
    engine_number varchar(16) not null default '',
    lasttime timestamp
);
insert into people
(zipcode,address,lastname,firstname,birthdate)
values
('230031','anhui','zhan','jindong','1989-09-15'),
('100000','beijing','zhang','san','1987-03-11'),
('200000','shanghai','wang','wu','1988-08-25')

insert into people_car
(people_id,plate_number,engine_number,lasttime)
values
(1,'A121311','12121313','2013-11-23 :21:12:21'),
(2,'B121311','1S121313','2011-11-23 :21:12:21'),
(3,'C121311','1211SAS1','2012-11-23 :21:12:21')

id

select标识符,是select的查询序列号。

  1. id相同表示加载表的顺序是从上到下。
  2. id不同id值越大,优先级越高,越先被执行。

select_type

表示select语句的类型

simple:表示简单查询

primary:表示主查询,或者最外层查询语句(union和subquery都会出现)

union:表示连接查询的第二个或者后面的查询语句

dependent union:UNION中第二个以及后面的SELECT语句,同时该语句依赖外部的查询。

explain select * from people where id in  (select id from people where zipcode = 100000 union select id from people where zipcode = 200000 );

img

这里顺带说下MySQL优化器对IN操作符的优化,优化器会将IN中的uncorrelated subquery优化成一个correlated subquery。

SELECT ... FROM t1 WHERE t1.a IN (SELECT b FROM t2);

类似这样的语句会被重写成这样:

SELECT ... FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.b = t1.a);

所以实际上被重写成这样:

explain select * from people o where exists  (select id from people where zipcode = 100000 and id = o.id union select id from people where zipcode = 200000  and id = o.id);

union result:连接查询的结果

subquery:子查询的第一个select语句

dependent subquery:子查询的第一个select,取决于外面的查询

derived:导出表的select(from子句的子查询)

table

显示的这一行信息是关于哪一张表的。有时候并不是真正的表名。

<derivedN>N就是id值,指该id值对应的那一步操作的结果。

还有<union*M,N*>这种类型,出现在UNION语句中

type

表示表的连接类型。从最佳类型到最差类型的顺序给出各种连接类型。

  1. system:仅有一行的系统表,是const连接类型的特例。找不到这玩意

  2. const:最多一个匹配行,在其余查询优化中作为常量。主要是主键和唯一索引

  3. eq_ref:对于每个来自前面的表的行组合,从后目标中读取一行。当一个索引的所有部分都在查询中使用,并且索引是unique或primary key时使用

    explain select * from sc,cou where sc.cno = cou.cno;
    sc为all,cou为eq_ref
    
  4. ref:这个类型跟eq_ref不同的是,它用在关联操作只使用了索引的最左前缀,或者索引不是UNIQUE和PRIMARY KEY。ref可以用于使用=或<=>操作符的带索引的列。

  5. ref_or_null:和名字一样,多添加了mysql专门搜索包含null值的行,子查询经常使用。

    explain select * from people_car2 where lasttime=current_time() or lasttime is null;
    lasttime设置为了普通索引
    
  6. index_merger:该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。关于索引合并优化看这里

  7. unique_subquery:该类型替换了下面形式的IN子查询的ref:

    value IN (SELECT primary_key FROM single_table WHERE some_expr)
    

    unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。

  8. index_subquery

    该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:

    value IN (SELECT key_column FROM single_table WHERE some_expr)
    
  9. range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range:

    explain select * from people where id = 1 or id = 2;
    
  10. index

    该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。这个类型通常的作用是告诉我们查询是否使用索引进行排序操作。

    explain select * from people order by id;
    
  11. all

possible_keys

possible_keys列指出MySQL能使用哪个索引在该表中找到行。

key

key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

key_len

key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好 。

ref

ref列显示使用哪个列或常数与key一起从表中选择行。

rows

rows列显示MySQL认为它执行查询时必须检查的行数。注意这是一个预估值。

Extra

Extra是EXPLAIN输出中另外一个很重要的列,该列显示MySQL在查询过程中的一些详细信息

索引失效

  1. like关键字%打头失效,因为B+树里是字典序,前面确定了可以利用索引
  2. 多列索引,最左前缀原则,左边优先级高,没有最左的话,B+树根本索引不到位置
  3. or关键字前后条件中但凡有一个非索引都失效
  4. 范围查询右侧失效,因为即使找到最左前缀范围,右侧还是无序的

优化子查询

子查询效率不高,用连接代替,不用建立临时表

优化数据库结构

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

可以把不常用的字段独立出一个表,如地址电话等

增加中间表

经常联合查询的数据建立中间表

增加冗余字段

规范化越高,表关系越多,连接越多,可以适当增加冗余,但是也容易造成多个表修改,自行判断

优化插入记录的速度

  1. 禁用索引:非空表大量插入时禁用索引,再开启

    alter table table_name disable keys;
    alter table table_name enable keys;
    
  2. 禁用唯一性检查

    set unique_checks=0;
    set unique_checks=1;
    
  3. 批量插入:用values后跟多个,而不是分开写。

  4. 使用load data infile批量导入:禁用唯一、外键、自动提交

分析表、检查表和优化表

analyze [local|no_write_to_binlog] table tbl_name[,...]

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

optimize [local|no_write_to_binlog] table tbl_name[,...]

优化MySQL服务器

优化服务器硬件

优化Mysql参数

临时表性能优化

服务器语句超时处理

创建全局通用表空间

新特性

支持不可见索引

增加资源组

原文地址:https://www.cnblogs.com/zwtcyt/p/14901953.html