您的位置:首页 > 数据库 > MySQL

MySQL查询性能调优化

2017-06-12 17:28 309 查看

一、索引的概念

索引:类似于字典的目录,设置索引可以 加速数据查找,对数据进行约束;

 

二、索引类型:

主键索引:保证数据唯一性,不能重复+不能为空

普通索引:加速数据查找

唯一索引:加速查找+不能重复

组合索引(多列组合成一个索引):

 

 

三、索引的工作原理

1、索引原理:

如果要查找的数据,没有设置索引,会从前到后地毯式搜索数据,如果设置了索引,会单独创建一张额外表,按某种格式保存该列数据位置,方便查找;


2、索引表的数据的格式

2.1、

hash格式:会把列中数据逐一hash成hash值(数字)对应数据的存储地址;

索引表:
数据hash值(数字) 存储位置(数字)

888 666

988 444

特点:索引表中的数据,和数据库表中数据顺序不一致了;(hash索引,适合单条数据查找,不适合范围查
找)

2.2、

Btree格式:二叉树,左侧放比自己小的数字,右侧放比自己大的数据

特点:范围查找速度快

id
查询顺序标识
如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B;
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL |    9 | NULL        |
|  2 | DERIVED     | tb1        | range | PRIMARY       | PRIMARY | 8       | NULL |    9 | Using where |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
特别的:如果使用union连接气值可能为null

select_type
查询类型
SIMPLE          简单查询
PRIMARY         最外层查询
SUBQUERY        映射为子查询
DERIVED         子查询
UNION           联合
UNION RESULT    使用联合的结果
...
table
正在访问的表名

type
查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
ALL             全表扫描,对于数据表从头到尾找一遍
select * from tb1;
特别的:如果有limit限制,则找到之后就不在继续向下扫描
select * from tb1 where email = 'seven@live.com'
select * from tb1 where email = 'seven@live.com' limit 1;
虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。

INDEX           全索引扫描,对索引从头到尾找一遍
select nid from tb1;

RANGE          对索引列进行范围查找
select *  from tb1 where name < 'alex';
PS:
between and
in
>   >=  <   <=  操作
注意:!= 和 > 符号

INDEX_MERGE     合并索引,使用多个单列索引搜索
select *  from tb1 where name = 'alex' or nid in (11,22,33);

REF             根据索引查找一个或多个值
select *  from tb1 where name = 'seven';

EQ_REF          连接时使用primary key 或 unique类型
select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;

CONST           常量
表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
select nid from tb1 where nid = 2 ;

SYSTEM          系统
表仅有一行(=系统表)。这是const联接类型的一个特例。
select * from (select nid from tb1 where nid = 1) as A;
possible_keys
可能使用的索引

key
真实使用的

key_len
MySQL中使用索引字节长度

rows
mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值

extra
该列包含MySQL解决查询的详细信息
“Using index”
此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
“Using where”
这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
“Using temporary”
这意味着mysql在对查询结果排序时会使用一个临时表。
“Using filesort”
这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
“Range checked for each record(index map: N)”
这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。

详细
View Code

 

七、慢日志查询

1、慢日志格式:


- 执行时间 > 10
- 未命中索引
- 日志文件路径

2、在MySQL命令行配置慢日志:

show variables like '%query%'
set global 变量名 = 值

 

3、在MySQL的配置文件配置慢日志:


mysqld --defaults-file='E:\wupeiqi\mysql-5.7.16-winx64\mysql-5.7.16-winx64\my-default.ini'

my.conf内容:
slow_query_log = ON
slow_query_log_file = D:/....

4、注意:修改配置文件之后,需要重启服务

 

八、limit分页**

无论是否有索引,limit分页是一个值得关注的问题

上下页间跳转:

基于当前页 的最大ID 和最小ID 推算上一页,下一页显示所需要的数据条目;

指定页间跳转:

求本页到跳转页所需要的数据,选择出所有ID。在选择

 

1、上页:获取当前页最大ID(假设显示当前页面:需要10条数据,当前页最小ID=20  最大ID=30)

 

步骤1:where条件筛选出 小于本页最小ID的数据,id=20----最开始数据行;

步骤2:找到本页之前的的数据行,倒序,取其中的10条,就是上页显示需要的数据;

SELECT * FROM day61.`user` WHERE id < 20 ORDER BY id DESC LIMIT 10;


2、下页:获取当前页最大ID(假设显示当前页面:需要10条数据,当前页最小ID=20 最大ID=30)

 

步骤1:where条件筛选出 大于本页最大ID的数据,id=30----最末尾的数据行;

步骤2:找到本页之后的的数据行,取其中的10条,就是下页显示需要的数据;

SELECT * FROM day61.`user` WHERE id >30 LIMIT 10;

 

3、上页  3、4、5、6、7、8......下页(跳转到指定页,假设显示当前页面:需要10条数据,当前页最小ID=20 最大ID=30

 

假设从 第3页跳转到第8页

步骤1:获取显示本页最大ID之后的数据行,limit(8-3)*10数据行

步骤2:获取了3-8行之间所有数据行 limit(10)就是显示跳转页所需数据;

步骤3、select id 获取显示该页所需要 数据行的,所有id,在选择跳转页 id;

select * from userinfo3 where id in (

select id from (select id from userinfo3 where id > max_id limit 30) as N order by N.id desc limit 10

获取跳转页数据行 所有的ID
)

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: