Mysql的执行计划、主键索引、建表语句解析

Mysql的执行计划:

执行explain+sql语句,你就能看到类似下图的结果:
在这里插入图片描述

id:
select查询的序列号

**1,当id相同时:**
执行顺序由上至下
**2、当id不同时:**
id越大,优先级越高,越先被执行

select_type:
查询的类型,主要是用于区分普通查询、联合查询、子查询等复杂的查询

1、SIMPLE:简单的select查询,查询中不包含子查询或者union
2、PRIMARY:查询中包含任何复杂的子部分,最外层查询则被标记为primary 
3、SUBQUERY:在select 或 where列表中包含了子查询 
4、DERIVED:在from列表中包含的子查询被标记为derived(衍生),mysql或递归执行这些子查询,把结果放在临时表里 
5、UNION:若第二个select出现在union之后,则被标记为union;若union包含在from子句的子查询中,外层select将被标记为derived 
6、UNION RESULT:从union表获取结果的select 

type:
访问类型,sql查询优化中一个很重要的指标,结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,好的sql查询至少达到range级别,最好能达到ref

1、system:表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,可以忽略不计
2、const:表示通过索引一次就找到了,const用于比较primary key 或者 unique索引。因为只需匹配一行数据,所有很快。如果将主键置于where列表中,mysql就能将该查询转换为一个const 
3、eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键 或 唯一索引扫描
4、ref:非唯一性索引扫描,返回匹配某个单独值的所有行。本质是也是一种索引访问,它返回所有匹配某个单独值的行,然而他可能会找到多个符合条件的行,所以它应该属于查找和扫描的混合体
5、range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了那个索引。一般就是在where语句中出现了bettween、<>、in等的查询。这种索引列上的范围扫描比全索引扫描要好。只需要开始于某个点,结束于另一个点,不用扫描全部索引
6、index:Full Index Scan,index与ALL区别为index类型只遍历索引树。这通常为ALL块,应为索引文件通常比数据文件小。(Index与ALL虽然都是读全表,但index是从索引中读取,而ALL是从硬盘读取)
7、ALL:Full Table Scan,遍历全表以找到匹配的行

possible_keys:
查询涉及到的字段上存在索引,则该索引将被列出,但不一定被查询实际使用

key:
实际使用的索引,如果为NULL,则没有使用索引。
查询中如果使用了覆盖索引,则该索引仅出现在key列表中

key_len:
表示索引中使用的字节数,查询中使用的索引的长度(最大可能长度),并非实际使用长度,理论上长度越短越好。key_len是根据表定义计算而得的,不是通过表内检索出的

ref:
显示索引的那一列被使用了,如果可能,是一个常量const。

rows:
根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数

Extra:
不适合在其他字段中显示,但是十分重要的额外信息

Mysql的建表语句:

索引被用来快速找出在一个列上用一特定值的行。没有索引,MySQL不得不首先以第一条记录开始并然后读完整个表直到它找出相关的行。
所有的MySQL索引(PRIMARY、UNIQUE和INDEX)在B树中存储。字符串是自动地压缩前缀和结尾空间。

primary key:
1、唯一标识mysql表中每条数据
2、该主键必须是唯一值,不可重复,也不可以是NULL
3、一般是自增id来作为primary key

CREATE TABLE stu_info (
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `stu_id` int(9) NOT NULL COMMENT '学生编号',
  `name` varchar(500) NOT NULL COMMENT '学生名称',
  `sex` varchar(20) NOT NULL COMMENT '学生性别',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='学生信息表'

unique key:
1、唯一主键可以是一个字段唯一,也可以是多个字段组合唯一
2、确保被设为唯一主键的一个或者多个字段在表中是唯一一条的
3、方便在我们往表中插入数据的时候,直接覆盖
例如:在使用replace into语句时,当插入的数据的一个或者多个字段的值跟表中的唯一主键对应的字段的值重复的时候,
就会先将表中的这个唯一主键对应的行delete,再需要插入的数据insert

CREATE TABLE stu_info (
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `stu_id` int(9) NOT NULL COMMENT '学生编号',
  `name` varchar(500) NOT NULL COMMENT '学生名称',
  `sex` varchar(20) NOT NULL COMMENT '学生性别',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `student_unique` (`stu_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='学生信息表'
或者
CREATE TABLE stu_info (
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `stu_id` int(9) NOT NULL COMMENT '学生编号',
  `name` varchar(500) NOT NULL COMMENT '学生名称',
  `sex` varchar(20) NOT NULL COMMENT '学生性别',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `student_unique` (`stu_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='学生信息表'

key:
mysql表的外键主要是用来加快查询速度的。

CREATE TABLE stu_info (
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `stu_id` int(9) NOT NULL COMMENT '学生编号',
  `name` varchar(500) NOT NULL COMMENT '学生名称',
  `sex` varchar(20) NOT NULL COMMENT '学生性别',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `student_unique` (`stu_id`) USING BTREE,
  KEY student_score(stu_id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='学生信息表'   

此处建表表示:该表的外键是stu_id,在mysql库中有一个表叫student_score表,stu_info和stu_score表的关联字段就会有stu_id
当然这样建表也是可以提高查询速度的

CREATE TABLE stu_info (
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `stu_id` int(9) NOT NULL COMMENT '学生编号',
  `name` varchar(500) NOT NULL COMMENT '学生名称',
  `sex` varchar(20) NOT NULL COMMENT '学生性别',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `student_unique` (`stu_id`) USING BTREE,
  KEY aaa (stu_id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='学生信息表'   

aaa是随机输入的,这个时候Key主要是提高查询速度

上述加上Key的表,在进行where操作,或者 where,join操作的时候,查询速度会大大提升
在我们优化sql的时候,可以考虑把where后面的字段设成外键。通过这样来提高效率(亲测从130秒->2秒)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值