最近在学习深入MySQL,记录一下学习历程和一些问题。

如何分析SQL的查询效率

在日常操作中,总会有一些查询得比较慢的SQL,但是造成查询慢的原因有很多,那么我们要怎么样才能准确的找到问题所在呢?
先创建一张表

drop table if exists index_test01;
create table `index_test01`(
	`id` int(11) NOT NULL AUTO_INCREMENT,/*AUTO_INCREMENT表示自增*/
`a` int(11) ,
`b` int(11) ,
`c` int(11) ,
`d` int(11) ,
PRIMARY KEY (`id`),/*主键*/
KEY `idx_a` (`a`),/*为a字段创建索引*/
KEY `idx_b_c` (`b`,`c`)/*为b,c字段创建联合索引*/
);
drop procedure if exists  insert_index_test01;  /*如果存储过程insert_index_test01存在就删除它*/
 delimiter $$ /*改变结束符  MYSQL的默认结束符为";"*/
create procedure insert_index_test01()  /*创建存储过程insert_index_test01*/
begin
declare i int;/*声明变量i*/
set i=1;/*设置i的初始值为1*/
while (i<100000)do /*循环10万次*/
insert into index_test01(a,b,c,d) values(i,i,i,i); /*自定义SQL  这里是为index_test01添加10万条数据*/
set i=i+1;
end while;
end $$
delimiter ;/*还原结束符*/
call insert_index_test01(); /* 运行存储过程insert_t9_1 */

想要看到明显的差距的话需要加表的数据
反复执行

创建完毕后 执行SQL

insert into index_test01(a,b,c,d)
select a,b,c,d from index_test01;

比如我们想看看下面SQL是否走了索引

select * from index_test01 where c=9000

只需要在SQL前 加上explain

explain select * from index_test01 where c=9000

mysql pg子查询性能_字段


下面是对这些字段的一些解释

explain相关字段解释

列名

注释

id

查询编号

select_type

查询类型

table

涉及到的表格

partitions

匹配的分区:查询将匹配记录所在的分区。仅当使用 partition 关键字时才显示该列。对于非分区表,该值为 NULL。

type

本次查询的表连接类型

possible_keys

可能选择的索引

key

实际选择的索引

key_len

被选择索引的长度

ref

与索引比较的列

rows

预计需要扫描的行数,对 InnoDB 来说,这个值是估值,并不一定准确

filtered

涉及到按条件筛选的行的百分比表格

Extra

附加信息

select_type常见参数

value

解释

SIMPLE

简单查询 (不使用关联查询或子查询)

PRIMARY

如果包含子查询或者关联查询,则最外层的查询部分标记为 primary

UNION

联合查询中第二个及后面的查询

DEPENDENT UNION

满足依赖外部的关联查询中第二个及以后的查询

UNION RESULT

联合查询的结果

SUBQUERY

子查询中的第一个查询

DEPENDENT SUBQUERY

子查询中的第一个查询,并且依赖外部查询

DERIVED

用到派生表的查询

MATERIALIZED

被物化的子查询

UNCACHEABLE SUBQUERY

一个子查询的结果不能被缓存,必须重新评估外层查询的每一行

UNCACHEABLE UNION

关联查询第二个或后面的语句属于不可缓存的子查询

type常见参数

value

解释

system

查询对象表只有一行数据,且只能用于 MyISAM 和 Memory 引擎的表,这是最好的情况

const

基于主键或唯一索引查询,最多返回一条结果

eq_ref

表连接时基于主键或非 NULL 的唯一索引完成扫描

ref

基于普通索引的等值查询,或者表间等值连接

fulltext

全文检索

ref_or_null

表连接类型是 ref,但进行扫描的索引列中可能包含 NULL 值

index_merge

利用多个索引

unique_subquery

子查询中使用唯一索引

index_subquery

子查询中使用普通索引

range

利用索引进行范围查询

index

全索引扫描

ALL

全表扫描

Extra常见参数

value

解释

Using filesort

将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序

Using temporary

需要创建一个临时表来存储结构,通常发生对没有索引的列进行 GROUP BY 时

Using index

使用覆盖索引

Using where

使用 where 语句来处理结果

Impossible WHERE

对 where 子句判断的结果总是 false 而不能选择任何数据

Using join buffer (Block Nested Loop)

关联查询中,被驱动表的关联字段没索引

Using index condition

先条件过滤索引,再查数据

Select tables optimized away

使用某些聚合函数(比如 max、min)来访问存在索引的某个字段时

如有补充,欢迎指点。