explain相关知识
-
[MySql]explain用法及实践写在前面explain对我们优化sql语句是非常有帮助的。可以通过explain+sql语句的方式分析当前sql语句。例子EXPLAIN SELECT dt,method,url FROM app_log WHERE id=11789table显示这一行数据属于哪张表,若在查询中为select起了别名,则显示别名。EXPLAIN SELECT dt,method,url FROM app_log AS temp WHERE id=11789type在表里查到结果所用的方式。包括(性能有差——>高): All | index | range | ref | eq_ref | const,system | null |all:全表扫描,MySQL 从头到尾扫描整张表查找行。EXPLAIN SELECT dt,method,url 
-
MySQL中EXPLAIN命令详解explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。 使用方法,在select语句前加上explain就可以了:如:?1234567mysql> explain select * from kt_course order by create_time desc;+----+-------------+-----------+------+---------------+------+---------+------+------+----------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-----------+------+---------------+------+--
-
MySQL优化之Explain命令解读简述: explain为mysql提供语句的执行计划信息。可以应用在select、delete、insert、update和place语句上。explain的执行计划,只是作为语句执行过程的一个参考,实际执行的过程不一定和计划完全一致,但是执行计划中透露出的讯息却可以帮助选择更好的索引和写出更优化的查询语句。EXPLAIN输出项(可参考mysql5.7文档)备注:当使用FORMAT=JSON, 返回的数据为json结构时,JSON Name为null的不显示。(参考文档:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html#explain-output-columns)ColumnJSON NameMeaningidselect_idThe SELECT identifierselect_typeNoneThe SELECT typetabletable_nameThe table for the output rowpartition
-
MySQL优化---EXPLAIN(mysq版本8.0)Explain命令是MySQL提供的内置命令,它的作用是向我们展示MySQL是如何执行sql语句的。SELECT, DELETE, INSERT, REPLACE, UPDATE 语句都可以使用Explain命令。EXPLAIN为SELECT语句中使用的每个table返回一行信息。它以MySQL在处理语句时的读取顺序列出所有的table。MySQL使用嵌套循环的方式解决所有的表连接(join)。这意味着MySQL从第一个table读取一行,然后在第二个table、第三个table中查找匹配的行,以此类推。当所有的table都被处理过时,MySQL会输出所选的列并在所有的table中进行反向跟踪,直到找到一个有更多匹配行的table。从该table中读取下一行,并继续处理下一个table。理解Explain输出的信息含义对SQL语句的优化有着至关重要的作用。 下面让我们详细解析下Explain命令输出的各字段的含义。Explain 输出的列:列名JSON 名(FORMAT=JSON)含义idsel
explain相关课程
explain相关教程
- 2.2 EXPLAIN explain是数据库自带的 SQL 分析工具,简单、实用且强大。下面我们以 MySQL 的explain工具为例来介绍一下它的使用。请先执行一下语句方便进行测试:DROP TABLE IF EXISTS imooc_user;CREATE TABLE imooc_user( id int PRIMARY KEY, username varchar(20), age int);INSERT INTO imooc_user(id,username,age)VALUES (1,'peter',18),(2,'pedro',24),(3,'jerry',22),(4,'mike',18),(5,'tom',20);2.2.1 使用 explainexplain的使用很简单,在它的后面接上需要分析的 SQL 语句即可,如下:EXPLAIN SELECT * FROM imooc_user WHERE id=1;执行成功后,得到如下结果:+----+-------------+------------+-------+---------------+---------+-------+------+----------+--------+| id | select_type | table | type | possible_keys | key | ref | rows | filtered | Extra |+----+-------------+------------+-------+---------------+---------+-------+------+----------+--------+| 1 | SIMPLE | imooc_user | const | PRIMARY | PRIMARY | const | 1 | 100.0 | <null> |+----+-------------+------------+-------+---------------+---------+-------+------+----------+--------+我们并未贴上全部结果,而是选取了其中重要的部分。id是SELECT语句的 id,select_type代表这次查询仅仅是一条简单的查询,table无需赘言,possible_keys表示可能用到的索引,extra是一些额外信息。而剩下的就是一些比较重要的信息了:type是针对单表的访问方法类型,const是常数类型,表示查询速度极快,在常数时间内即可返回;key表示使用到的索引,PRIMARY表示用到了主键索引;ref意思是使用索引等值查询时,与索引列比较的对象信息,这个比较抽象,大致的意思是,索引使用了何种类型进行比较,const即使用常数比较,id 1 就是常数;rows是预估需要读取记录的条数,1代表只需要读取一行,rows 越小越好;filtered表示查询过滤后未搜索到的记录百分比,100.0表示未搜索到的几乎占100%,filtered 越大越好。因此从分析结果可以看出,这条语句性能极好,除非数据库波动,否则完全不用担心查询速度问题。2.2.2 explain 优化 SQL那么什么样的语句查询效率比较低了,我们看一下这个语句:EXPLAIN SELECT * FROM imooc_user WHERE age=22;分析结果如下:+----+-------------+------------+------+---------------+--------+--------+------+----------+-------------+| id | select_type | table | type | possible_keys | key | ref | rows | filtered | Extra |+----+-------------+------------+------+---------------+--------+--------+------+----------+-------------+| 1 | SIMPLE | imooc_user | ALL | <null> | <null> | <null> | 5 | 20.0 | Using where |+----+-------------+------------+------+---------------+--------+--------+------+----------+-------------+我们仍然截取了部分信息,我们将目光聚焦在type和rows上,这里的type不再是const而是ALL,ALL表示全表扫描,是最慢的一个级别,rows为5,表示这次查询将会扫描5条记录,而我们总共才5条记录。这个查询的性能是极为糟糕的,试想一下,如果该表的数据是几万行乃至几十万行,一次查询得扫描全部,那得多慢啊。既然这么慢,可以优化吗?当然可以,如果你有相关的经验,第一个想到的就是建索引。CREATE INDEX age_index ON imooc_user(age);索引建立完毕后,我们再次分析:EXPLAIN SELECT * FROM imooc_user WHERE age=22;+----+-------------+------------+------+---------------+-----------+-------+------+----------+--------+| id | select_type | table | type | possible_keys | key | ref | rows | filtered | Extra |+----+-------------+------------+------+---------------+-----------+-------+------+----------+--------+| 1 | SIMPLE | imooc_user | ref | age_index | age_index | const | 1 | 100.0 | <null> |+----+-------------+------------+------+---------------+-----------+-------+------+----------+--------+type从ALL变成了ref,rows也仅仅只有1行;ref也是一种速度很快的类型,即查询使用到了常数匹配索引,在结果中key字段也指明了,该次查询有使用到我们新建的索引age_index。explain 的内容很多,而且不同的数据库的实现也不同,如果你需要使用它,请按照你使用的数据库查阅该数据库权威的文档来学习。
- 5.2 不能通过索引进行排序的查询 使用两种不同的排序方向:mysql> explain select * from customer where last_name = 'Allen' order by first_name desc, birth_date asc\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: refpossible_keys: idx_customer key: idx_customer key_len: 93 ref: const rows: 1 filtered: 100.00 Extra: Using index condition; Using filesort1 row in set, 1 warning (0.00 sec)order by 子句引用了一个不在索引的列:mysql> explain select * from customer where last_name = 'Allen' order by first_name, gender\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: refpossible_keys: idx_customer key: idx_customer key_len: 93 ref: const rows: 1 filtered: 100.00 Extra: Using index condition; Using filesort1 row in set, 1 warning (0.00 sec)where 条件和 order by 的列无法组成索引的最左前缀:mysql> explain select * from customer where last_name = 'Allen' order by birth_date\G第一列是范围查询,where 条件和 order by 的列无法组成索引的最左前缀:mysql> explain select * from customer where last_name between 'Allen' and 'Bush' order by first_name\G第一列是常量,第二列是范围查询(多个等于也是范围查询):mysql> explain select * from customer where last_name = 'Allen' and first_name in ('Cuba','Kim') order by birth_date\G
- 5.1 可以通过索引进行排序的查询 索引的列顺序和 order by 子句的顺序完全一致:mysql> explain select last_name,first_name from customer order by last_name, first_name, birth_date\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: indexpossible_keys: NULL key: idx_customer key_len: 190 ref: NULL rows: 1 filtered: 100.00 Extra: Using index1 row in set, 1 warning (0.00 sec)索引的第一列指定为常量:从 explain 可以看到没有出现排序操作(filesort):mysql> explain select * from customer where last_name = 'Allen' order by first_name, birth_date\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: refpossible_keys: idx_customer key: idx_customer key_len: 93 ref: const rows: 1 filtered: 100.00 Extra: Using index condition1 row in set, 1 warning (0.00 sec)索引的第一列指定为常量,使用第二列排序:mysql> explain select * from customer where last_name = 'Allen' order by first_name desc\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: refpossible_keys: idx_customer key: idx_customer key_len: 93 ref: const rows: 1 filtered: 100.00 Extra: Using where1 row in set, 1 warning (0.00 sec)索引的第一列为范围查询,order by 使用的两列为索引的最左前缀:mysql> explain select * from customer where last_name between 'Allen' and 'Bush' order by last_name,first_name\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: rangepossible_keys: idx_customer key: idx_customer key_len: 93 ref: NULL rows: 1 filtered: 100.00 Extra: Using index condition1 row in set, 1 warning (0.00 sec)
- 1.2 适合 B-Tree 索引的查询类型 全值匹配和索引中的所有列进行匹配,如查找姓名为 George Bush、1960-08-08 出生的客户。mysql> explain select * from customer where first_name='George' and last_name='Bush' and birth_date='1960-08-08'\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: refpossible_keys: idx1_customer key: idx1_customer key_len: 190 ref: const,const,const rows: 1 filtered: 100.00 Extra: NULL1 row in set, 1 warning (0.00 sec)匹配最左前缀只使用索引的第一列,如查找所有姓氏为 Bush 的客户:mysql> explain select * from customer where last_name='Bush'\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: refpossible_keys: idx1_customer key: idx1_customer key_len: 93 ref: const rows: 1 filtered: 100.00 Extra: NULL1 row in set, 1 warning (0.00 sec)匹配列前缀只匹配某一列的值的开头部分,如查找所有以 B 开头的姓氏的客户,这里使用了索引的第一列:mysql> explain select * from customer where last_name like 'B%'\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: rangepossible_keys: idx1_customer key: idx1_customer key_len: 93 ref: NULL rows: 1 filtered: 100.00 Extra: Using index condition1 row in set, 1 warning (0.00 sec)匹配范围值查找所有姓氏在 Allen 和 Bush 之间的客户,这里使用了索引的第一列:mysql> explain select * from customer where last_name between 'Allen' and 'Bush'\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: rangepossible_keys: idx1_customer key: idx1_customer key_len: 93 ref: NULL rows: 1 filtered: 100.00 Extra: Using index condition1 row in set, 1 warning (0.00 sec)精确匹配某一列,并范围匹配另一列第一列全匹配,第二列范围匹配,如查找姓氏为 Bush,名字以 G 开头的客户:mysql> explain select * from customer where last_name='Bush' and first_name like 'G'\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: rangepossible_keys: idx1_customer key: idx1_customer key_len: 186 ref: NULL rows: 1 filtered: 100.00 Extra: Using index condition1 row in set, 1 warning (0.00 sec)只访问索引的查询只需要访问索引即可获取数据,不需要回表访问数据行,这种查询也叫覆盖索引:mysql> explain select last_name from customer where last_name='Bush'\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: refpossible_keys: idx1_customer key: idx1_customer key_len: 93 ref: const rows: 1 filtered: 100.00 Extra: Using index1 row in set, 1 warning (0.00 sec)除了上述这些查询类型外,索引还可以用于 order by 排序操作,因为索引中的节点是有序的。如果 B-Tree 可以按照某种方式查找到数据,那么也可以按照这种方式进行排序。
- 1.3 B-Tree 索引的限制 如果不是按照索引的最左列开始查找数据,则无法使用索引。如查找名字为 George 的客户:mysql> explain select * from customer where first_name='George'\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1 filtered: 100.00 Extra: Using where1 row in set, 1 warning (0.00 sec)不能跳过索引的列。如查找姓氏为 Bush,生日为 1960-08-08 的客户,这种查询只能使用索引的第一列:mysql> explain select * from customer where last_name='Bush' and birth_date='1960-08-08'\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: refpossible_keys: idx1_customer key: idx1_customer key_len: 93 ref: const rows: 1 filtered: 100.00 Extra: Using index condition1 row in set, 1 warning (0.00 sec)如果查询中有某个列的范围查询,在其右边的列都无法使用索引进行查找数据。如查找姓氏为以 B 开头,名字为 George 的客户。这个查询只能使用第一列,因为 like 是一个范围查询:mysql> explain select * from customer where last_name like 'B%' and first_name='George'\G;*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: rangepossible_keys: idx1_customer key: idx1_customer key_len: 186 ref: NULL rows: 1 filtered: 100.00 Extra: Using index condition1 row in set, 1 warning (0.00 sec)
- 4. 覆盖索引 如果一个索引包含所有需要查询的字段,称之为覆盖索引。由于覆盖索引无须回表,通过扫描索引即可拿到所有的值,它能极大地提高查询效率:索引条目一般比数据行小的多,只通过扫描索引即可满足查询需求,MySQL 可以极大地减少数据的访问量。表 customer 有一个多列索引 (first_name,last_name),以下查询只需要访问 first_name 和last_name,这时就可以通过这个索引来实现覆盖索引。mysql> explain select last_name, first_name from customer\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: customer partitions: NULL type: indexpossible_keys: NULL key: idx1_customer key_len: 186 ref: NULL rows: 1 filtered: 100.00 Extra: Using index1 row in set, 1 warning (0.00 sec)当查询为覆盖索引查询时,在 explain 的 extra 列可以看到 Using index。
explain相关搜索
-
e preventdefault
e4a
each
each的用法
easter
easter day
easyui
easyui 官网
echarts
eclipse
eclipse 64位下载
eclipse android
eclipse tomcat
eclipse 教程
eclipse 快捷键
eclipseadt
eclipse安装教程
eclipse插件
eclipse插件下载
eclipse教程