一、MYSQL的索引

索引(Index):帮助Mysql高效获取数据的一种数据结构。用于提高查找效率,可以比作字典。可以简单理解为排好序的快速查找的数据结构。
索引的作用:便于查询和排序(所以添加索引会影响where 语句与 order by 排序语句)。
在数据之外,数据库还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用数据。这样就可以在这些数据结构上实现高级查找算法。这些数据结构就是索引。
索引本身也很大,不可能全部存储在内存中,所以索引往往以索引文件的形式存储在磁盘上。
我们平时所说的索引,如果没有特别指明,一般都是B树索引。(聚集索引、复合索引、前缀索引、唯一索引默认都是B+树索引),除了B树索引还有哈希索引。

优点:A、提高数据检索效率,降低数据库的IO成本
B、通过索引列对数据进行排序,降低了数据排序成本,降低了CPU的消耗。
缺点:A、索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引也是占用空间的。
B、对表进行INSERT、UPDATE、DELETE操作时,MYSQL不仅会更新数据,还要保存一下索引文件每次更新添加了索引列字段的相应信息。
在实际的生产环境中我们需要逐步分析,优化建立最优的索引,并要优化我们的查询条件。

索引的分类:1、单值索引 一个索引只包含一个字段,一个表可以有多个单列索引。
2、唯一索引 索引列的值必须唯一,但允许有空值。
3、复合索引 一个索引包含多个列
一张表建议建立5个之内的索引

语法:

创建 1、CREATE [UNIQUE] INDEX indexName ON myTable (columnName(length));
         2、ALTER myTable Add [UNIQUE] INDEX [indexName] ON (columnName(length));
删除:DROP INDEX [indexName] ON myTable;
查看: SHOW INDEX FROM table_name\G;

二、EXPLAIN 的作用

EXPLAIN :模拟Mysql优化器是如何执行SQL查询语句的,从而知道Mysql是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。

mysql> explain select * from tb_user;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| | SIMPLE | tb_user | ALL | NULL | NULL | NULL | NULL | | NULL |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+

(一)id列:

(1)、id 相同执行顺序由上到下
mysql> explain
-> SELECT*FROM tb_order tb1
-> LEFT JOIN tb_product tb2 ON tb1.tb_product_id = tb2.id
-> LEFT JOIN tb_user tb3 ON tb1.tb_user_id = tb3.id;
+----+-------------+-------+--------+---------------+---------+---------+---------------------------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+---------------------------+------+-------+
| 1 | SIMPLE | tb1 | ALL | NULL | NULL | NULL | NULL | 1 | NULL |
| 1 | SIMPLE | tb2 | eq_ref | PRIMARY | PRIMARY | 4 | product.tb1.tb_product_id | 1 | NULL |
| 1 | SIMPLE | tb3 | eq_ref | PRIMARY | PRIMARY | 4 | product.tb1.tb_user_id | 1 | NULL |
+----+-------------+-------+--------+---------------+---------+---------+---------------------------+------+-------+ (2)、如果是子查询,id序号会自增,id值越大优先级就越高,越先被执行。
mysql> EXPLAIN
-> select * from tb_product tb1 where tb1.id = (select tb_product_id from tb_order tb2 where id = tb2.id =1);
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
| 1 | PRIMARY | tb1 | const | PRIMARY | PRIMARY | 4 | const | 1 | NULL |
| 2 | SUBQUERY | tb2 | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
(3)、id 相同与不同,同时存在 mysql> EXPLAIN
-> select * from(select * from tb_order tb1 where tb1.id =1) s1,tb_user tb2 where s1.tb_user_id = tb2.id;
+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------+
| 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | NULL |
| 1 | PRIMARY | tb2 | const | PRIMARY | PRIMARY | 4 | const | 1 | NULL |
| 2 | DERIVED | tb1 | const | PRIMARY | PRIMARY | 4 | const | 1 | NULL |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------+
derived2:衍生表 2表示衍生的是id=2的表 tb1

(二)select_type列:数据读取操作的操作类型
  1、SIMPLE:简单的select 查询,SQL中不包含子查询或者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

(三)table列:该行数据是关于哪张表

(四)type列:访问类型  由好到差system > const > eq_ref > ref > range > index > ALL

  1、system:表只有一条记录(等于系统表),这是const类型的特例,平时业务中不会出现。
  2、const:通过索引一次查到数据,该类型主要用于比较primary key 或者unique 索引,因为只匹配一行数据,所以很快;如果将主键置于WHERE语句后面,Mysql就能将该查询转换为一个常量。
  3、eq_ref:唯一索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或者唯一索引扫描。
  4、ref:非唯一索引扫描,返回匹配某个单独值得所有行,本质上是一种索引访问,它返回所有匹配某个单独值的行,就是说它可能会找到多条符合条件的数据,所以他是查找与扫描的混合体。

  详解:这种类型表示mysql会根据特定的算法快速查找到某个符合条件的索引,而不是会对索引中每一个数据都进行一 一的扫描判断,也就是所谓你平常理解的使用索引查询会更快的取出数据。而要想实现这种查找,索引却是有要求的,要实现这种能快速查找的算法,索引就要满足特定的数据结构。简单说,也就是索引字段的数据必须是有序的,才能实现这种类型的查找,才能利用到索引。

  5、range:只检索给定范围的行,使用一个索引来选着行。key列显示使用了哪个索引。一般在你的WHERE 语句中出现between 、< 、> 、in 等查询,这种给定范围扫描比全表扫描要好。因为他只需要开始于索引的某一点,而结束于另一点,不用扫描全部索引。
  6、index:FUll Index Scan 扫描遍历索引树(index:这种类型表示是mysql会对整个该索引进行扫描。要想用到这种类型的索引,对这个索引并无特别要求,只要是索引,或者某个复合索引的一部分,mysql都可能会采用index类型的方式扫描。但是呢,缺点是效率不高,mysql会从索引中的第一个数据一个个的查找到最后一个数据,直到找到符合判断条件的某个索引)。

  7、ALL 全表扫描 从磁盘中获取数据 百万级别的数据ALL类型的数据尽量优化。

(五)possible_keys列:显示可能应用在这张表的索引,一个或者多个。查询涉及到的字段若存在索引,则该索引将被列出,但不一定被查询实际使用。
(六)keys列:实际使用到的索引。如果为NULL,则没有使用索引。查询中如果使用了覆盖索引,则该索引仅出现在key列表中。覆盖索引:select 后的 字段与我们建立索引的字段个数一致。

(七)ken_len列:表示索引中使用的字节数,可通过该列计算查询中使用的索引长度。在不损失精确性的情况下,长度越短越好。key_len 显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出来的。
(八)ref列:显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值。
(九)rows列(每张表有多少行被优化器查询):根据表统计信息及索引选用的情况,大致估算找到所需记录需要读取的行数。

(十)Extra列:扩展属性,但是很重要的信息。

 1、 Using filesort(文件排序):mysql无法按照表内既定的索引顺序进行读取。
mysql> explain select order_number from tb_order order by order_money;
+----+-------------+----------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | tb_order | ALL | NULL | NULL | NULL | NULL | 1 | Using filesort |
+----+-------------+----------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)
说明:order_number是表内的一个唯一索引列,但是order by 没有使用该索引列排序,所以mysql使用不得不另起一列进行排序。
2、Using temporary:Mysql使用了临时表保存中间结果,常见于排序order by 和分组查询 group by。 mysql> explain select order_number from tb_order group by order_money;
+----+-------------+----------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+------+---------------------------------+
| 1 | SIMPLE | tb_order | ALL | NULL | NULL | NULL | NULL | 1 | Using temporary; Using filesort |
+----+-------------+----------+------+---------------+------+---------+------+------+---------------------------------+
1 row in set (0.00 sec)
3、Using index 表示相应的select 操作使用了覆盖索引,避免访问了表的数据行,效率不错。
如果同时出现Using where ,表明索引被用来执行索引键值的查找。
如果没有同时出现using where 表明索引用来读取数据而非执行查找动作。
mysql> explain select order_number from tb_order group by order_number;
+----+-------------+----------+-------+--------------------+--------------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+--------------------+--------------------+---------+------+------+-------------+
| 1 | SIMPLE | tb_order | index | index_order_number | index_order_number | 99 | NULL | 1 | Using index |
+----+-------------+----------+-------+--------------------+--------------------+---------+------+------+-------------+
1 row in set (0.00 sec) 4、Using where 查找
5、Using join buffer :表示当前sql使用了连接缓存。
6、impossible where :where 字句 总是false ,mysql 无法获取数据行。
7、select tables optimized away:
8、distinct:

下一章:Mysql 学习之EXPLAIN实战

Mysql 学习之EXPLAIN作用的更多相关文章

  1. MySQL学习系列2--MySQL执行计划分析EXPLAIN

    原文:MySQL学习系列2--MySQL执行计划分析EXPLAIN 1.Explain语法 EXPLAIN SELECT …… 变体:   EXPLAIN EXTENDED SELECT …… 将执行 ...

  2. MySQL学习系列2--MySQL执行计划分析EXPLAIN [原创]

    1.Explain语法 EXPLAIN SELECT …… 变体:   EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可 ...

  3. 我的MYSQL学习心得(九) 索引

    我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  4. 我的MYSQL学习心得(十六) 优化

    我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  5. 我的MYSQL学习心得(九)

    原文:我的MYSQL学习心得(九) 我的MYSQL学习心得(九) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL ...

  6. mysql学习【第5篇】:事务索引备份视图

    狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! mysql学习[第5篇]:事务索引备份视图 MySQL事务 事务就是将一组SQL语句放在同一批次 ...

  7. MySQL 学习四 SQL优化

    MySQL逻辑架构: 第一层:客户端层,连接处理,授权认证,安全等功能.   第二层:核心层,查询解析,分析,优化,缓存,内置函数(时间,数学,加密),存储过程,触发器,视图   第三层:存储引擎.负 ...

  8. 数据库MySQL学习笔记高级篇

    数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...

  9. 一千行MySQL学习笔记 (转)

    出处:  一千行MySQL学习笔记 /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权 ...

随机推荐

  1. 可以用 Python 编程语言做哪些神奇好玩的事情?

    作者:造数科技链接:https://www.zhihu.com/question/21395276/answer/219747752 使用Python绘图 我们先来看看,能画出哪样的图 更强大的是,每 ...

  2. 手机设备访问PC页面如果跳转到手机页面?

    //例如:iphone访问www.baidu.com自动跳转到wap.baidu.com,只需在pc端模版页面引入以下js代码//pc zhuan mobile var mobileAgent = n ...

  3. 201521123084 《Java程序设计》第4周学习总结

    第4周作业-面向对象设计与继承 1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 总结: (1)学会了如何给类和方法进行简单的注释: (2)学 ...

  4. 201521123009 《Java程序设计》第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 Q1:List中指定元素的删除(题目4-1) 1.1 实验总结 Scanne ...

  5. 201521123105《jave程序》第二周学习总结

    1. 本周学习总结 学习了各种java数据类型以及各种运算符的使用 学习了一维,二维数组的用法 学习了String类对象使用 2. 书面作业 使用Eclipse关联jdk源代码,并查看String对象 ...

  6. 201521123115《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...

  7. 201521123092《java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  8. Eclipse rap 富客户端开发总结(6) : 如何发布rap到tomcat

    1.先下载以来的打包插件 war products  输入下面的地址,选择相应的插件 新建一个 war product Configutation向导 下面的war  product Configut ...

  9. 推荐一个比FiddlerCore好用的HTTP(S)代理服务器

    为什么不用FiddlerCore? 说到FiddlerCore大家可能会比较陌生,那么它哥Fiddler就比较熟悉了:抓包.模拟低带宽.修改请求我平时比较常用.Fiddler的本质就是一个HTTP代理 ...

  10. Fiddler抓包工具使用详解

    一.Fiddler简介 Fiddler是最强大最好用的Web调试工具之一, 它能记录所有客户端和服务器的http和https请求.允许你监视.设置断点.甚至修改输入输出数据.Fiddler包含了一个强 ...