缅甸新锦江赌场-官方网站

English 浙江双荣电子
0577-62816098

产品分类

/PRODUCTS

  联系我们

双荣在线
双荣在线
CONTACT US

电话:0577-62816098

传真:0577-62816098

E-mail:1620486953@qq.com

新闻分类

/NEWS

新闻中心

当前位置:首页 >> 新闻中心 >> 详解二次接线端子铜质螺丝材质之普通黄铜

EXPLAIN命令详解学习,常用的优化步骤

来源:缅甸新锦江 2019-08-03 06:50

  • 什么样利用索引?
  • 应用索引应该小心的事项
  • 翻看索引使用意况

 6. Impossible where

2.1 key
 key 列建议优化器选拔选用的目录。一般的话SQL 查询中的每一个表都仅使用贰个索引。也设有索引合并的少数例外情状,如给定表上用到了四个恐怕更加多索引。
 上面是QEP 中key 列的言传身教:
 key: item_id
 key: NULL
 key: first, last
 SHOW CREATE TABLE <table>命令是最简便的查看表和索引列细节的秘技。和key 列相关的列还包罗possible_keys、rows 以及key_len。

 贰、定位功能低的SQL

  上面也关系过慢查询那么些概念重若是用来划分功效低的SQL,可是慢查询是在方方面面查询截止后才记录的,所以光是靠慢查询日志是追踪不了效用低的SQL。一般有二种办法固定作用低的SQL:

  1、通过慢查询日志查看功用低的SQL语句,慢查询日志是因而show_query_log_file钦点期存款款和储蓄路线的,里面著录全数超越long_query_time的SQL语句(关于日志的查看,日后再一步研商学习),不过供给慢查询日志的发出是在询问结束后才有的。

  2、经过show processlist命令查看当前MySQL进行的线程,能够见到线程的场合新闻

mysql> show processlist;
+----+------+-----------------+------+---------+------+----------+------------------+
| Id | User | Host            | db   | Command | Time | State    | Info             |
+----+------+-----------------+------+---------+------+----------+------------------+
|  2 | root | localhost:58377 | NULL | Sleep   | 2091 |          | NULL             |
|  3 | root | localhost:58382 | test | Sleep   | 2083 |          | NULL             |
|  4 | root | localhost:58386 | test | Sleep   | 2082 |          | NULL             |
|  5 | root | localhost:59092 | test | Query   |    0 | starting | show processlist |
+----+------+-----------------+------+---------+------+----------+------------------+
4 rows in set

  个中重点的是state字段,表示目前SQL语句线程的图景,如Sleeping 表示正在等候客户端发送新请求,Sending data把询问到的data结果发送给客户端等等,具体请看

  const 当以此表最八唯有壹行相配的行时出现system 那是const 的特例,当表唯有三个row 时会出现

  1. CREATE TABLE `wp_posts` (  
  2.  `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
  3.  `post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',  
  4.  `post_status` varchar(20) NOT NULL DEFAULT 'publish' ,  
  5.  `post_type` varchar(20) NOT NULL DEFAULT 'post',  
  6.  PRIMARY KEY (`ID`),  
  7.  KEY `type_status_date`(`post_type`,`post_status`,`post_date`,`ID`)  
  8. ) DEFAULT CHARSET=utf8  
  9.   
  10.  CREATE TABLE `wp_posts` (  
  11.  `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
  12.  `post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',  
  13.  `post_status` varchar(20) NOT NULL DEFAULT 'publish' ,  
  14.  `post_type` varchar(20) NOT NULL DEFAULT 'post',  
  15.  PRIMARY KEY (`ID`),  
  16.  KEY `type_status_date`(`post_type`,`post_status`,`post_date`,`ID`)  
  17. ) DEFAULT CHARSET=utf8  

一言九鼎参考资料:《长远浅出MySQL》,

 2 rows in set (0.00 sec)

  1. mysql> SHOW SESSION STATUS LIKE 'Handler_read%';  
  2.  +-----------------------+-------+  
  3.  | Variable_name         | Value |  
  4.  +-----------------------+-------+  
  5.  | Handler_read_first    | 0     |  
  6.  | Handler_read_key      | 0     |   
  7.  | Handler_read_last     | 0     |  
  8.  | Handler_read_next     | 0     |  
  9.  | Handler_read_prev     | 0     |  
  10.  | Handler_read_rnd      | 0     |  
  11.  | Handler_read_rnd_next | 11    |  
  12.  +-----------------------+-------+  
  13.  7 rows in set (0.00 sec)  

四、因人而异选取优化措施-----------举例选择index举行优化

 select_type: SIMPLE

 4. Using index
 那几个值入眼重申了只供给动用索引就足以满意查询表的渴求,无需直接待上访问表数据。请参见第陆章的事无巨细示例来领会那
 个值。

二、定位怎么样须求优化的SQL------------通过慢查询记录+show processlist命令查看当前线程

 | Variable_name | Value |

**

  • 有关列简单表达:type、table、select_type...

 mysql> EXPLAIN SELECT * FROM user WHERE 1=2;

这些UPDATE语句可以被重写成为上面那样的SELECT语句:

一、使用索引优化的比喻

  上个例子大家看到到施行explain select*from user where name='Lisi',扫描了3行(全体行数)使用了全表寻觅all。若是实在专业中name是常事用到查询的字段(是指日常跟在where后的字段,不是select后的字段)并且数据量不小的景况呢?这时候就需求索引了(索引平常用到where前边的字段比select前面包车型地铁字段效果更加好,或许说正是要运用在where前面包车型地铁字段上)

充实name前缀索引(这里只是比喻,并从未选用最合适的前缀):

mysql> create index index_name on user(name(2));
Query OK, 0 rows affected
Records: 0  Duplicates: 0  Warnings: 0

执行explain分析

mysql> explain select*from user where name = 'Lisi';
+----+-------------+-------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key        | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ref  | index_name    | index_name | 9       | const |    1 |      100 | Using where |
+----+-------------+-------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
1 row in set

  能够看来type变为ref、rows降为一(实际上如若使用了目录都以壹),filtered过滤百分比为百分百,实际利用的目录为index_name。借使数据量相当大的话使用索引就是很好的优化措施,对于如何选拔索引,哪天用索引,笔者做出了如下总计:

 

 2.8 Extra
 Extra 列提供了有关分歧品类的MySQL 优化器路线的一密密麻麻
 额外音信。Extra 列可以蕴含几个值,可以有那多个区别的取值,并
 且那么些值还在乘胜MySQL 新本子的揭橥而尤为充实。上边给
 出常用值的列表。你能够从底下的地点找到更周到的值的列表:
 。


SQL 语句的。那条命令并未提供其余调度提议,但它能够提供至关心注重要的音信帮忙您做出调优决策。

 1. Using where
 那个值表示查询利用了where 语句来管理结果——举例实践
 全表扫描。假使也使用了目录,那么行的界定标准是因此得到必
 要的数码之后管理读缓冲区来落到实处的。

 

  +-----------------------+-------+

  1. mysql> EXPLAIN SELECT * FROM inventory WHERE item_id = 16102176\G;  
  2.   ********************* 1. row ***********************  
  3.   id: 1  
  4.   select_type: SIMPLE  
  5.   table: inventory  
  6.   type: ALL  
  7.   possible_keys: NULL  
  8.   key: NULL  
  9.   key_len: NULL  
  10.   ref: NULL  
  11.   rows: 787338  
  12.   Extra: Using where  

一、查看SQL的实践成效---------------使用show status命令

  table: inventory

 
 在SELECT查询的拉长1个post_status 列的界定条件后,QEP突显key_len 的值为13二,那象征post_type、post_status、post_date
 三列(6二+62+八,(20×三)+2,(20×三)+2,八)都被用到了。别的,这一个目录的主码列ID 的概念是运用MyISAM 存款和储蓄索
 引的残留印迹。当使用InnoDB 存款和储蓄引擎时,在非主码索引中隐含主码列是剩下的,那能够从key_len 的用法看出来。
 相关的QEP 列还包罗富含Using index 值的Extra 列。
 
 2.5 table
 table 列是EXPLAIN 命令输出结果中的三个独立行的头一无二标记符。那个值也许是表名、表的小名大概一个为查询发生有的时候表
 的标志符,如派生表、子查询或集结。上面是QEP 中table 列的一部分演示:
 table: item
 table: <derivedN>
 table: <unionN,M>
 表中N 和M 的值参照他事他说加以调查了另一个符合id 列值的table 行。相关的QEP 列还有select_type

壹、查看SQL施行成效

  使用show [session|gobal] status命令精晓SQL推行功用、线程缓存内的线程的数据、当前开荒的接连的数量、得到的表的锁的次数等。

举个例子说实施show status like 'Com_%'查看种种语句施行的次数即频率,当中Com_xxx中xxx代表便是话语,比如Com_select:实施select操作的次数。

 1 mysql> use test;
 2 Database changed
 3 mysql> show status like 'Com_%';
 4 +-----------------------------+-------+
 5 | Variable_name               | Value |
 6 +-----------------------------+-------+
 7 | Com_admin_commands          | 0     |
 8 | Com_assign_to_keycache      | 0     |
 9 | Com_alter_db                | 0     |
10 | Com_alter_db_upgrade        | 0     |
11 | Com_alter_event             | 0     |
12 | Com_alter_function          | 0     |
13 | Com_alter_instance          | 0     |
14 | Com_alter_procedure         | 0     |
15 | Com_alter_server            | 0     |
16 | Com_alter_table             | 0     |
17 | Com_alter_tablespace        | 0     |
18 | Com_alter_user              | 0     |
19 | Com_analyze                 | 0     |
20 | Com_begin                   | 0     |
21 | Com_binlog                  | 0     |
22 | Com_call_procedure          | 0     |
23 | Com_change_db               | 2     |
24 | Com_change_master           | 0     |
25 | Com_change_repl_filter      | 0     |
26 | Com_check                   | 0     |
27 | Com_checksum                | 0     |
28 | Com_commit                  | 0     |
29 | Com_create_db               | 0     |
30 | Com_create_event            | 0     |
31 | Com_create_function         | 0     |
32 | Com_create_index            | 0     |
  ..............................

比如实施show status like 'slow_queries'查看慢查询次数(黄人问号??什么是慢查询呢?正是通过安装查询时间阈值long_query_time(0-10s)并打开开关show_query_log(一=OFF/0=ON),当超过那几个阈值的查询都称为慢查询,常常用来划分试行SQL效能)

mysql> show status like 'slow_queries';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries  | 0     |
+---------------+-------+
1 row in set

例如说实践show status like 'uptime'查看服务工作时间(即运转时刻):

mysql> show status like 'uptime';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Uptime        | 21645 |
+---------------+-------+
1 row in set

比方说施行show status like 'connections'查看MySQL连接数:

mysql> show status like 'connections';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Connections   | 6     |
+---------------+-------+
1 row in set

  通过show [session|gobal] status命令很精通地观察如何SQL实行效能不及人意,可是实际是怎么个不及意法,还得继续往下看,使用EXPLAIN命令剖判现实的SQL语句

 业要求的例证。那个查询能够用三种不一样的点子组织。固然会生出同样的结果,但QEP 会显示二种分化的路径。

 2. PRIMARY
 那是为更目不暇接的询问而创设的主要表(也正是最外层的表)。这一个类型一般能够在DE安德拉IVED 和UNION 类型混合使用时看到。
 
 3. DERIVED
 当三个表不是3个物理表时,那么就被叫做DELacrosseIVED。上面包车型地铁SQL 语句给出了3个QEP 中DEOdysseyIVED select-type 类型的
 示例:
 mysql> EXPLAIN SELECT MAX(id)
 -> FROM (SELECT id FROM users WHERE first = 'west') c;

 

 ********************* 2. row ***********************

 6. Impossible where
 那个值强调了where 语句会导致未有符合条件的行。请看上边包车型客车亲自过问:
 mysql> EXPLAIN SELECT * FROM user WHERE 1=2;

在始发博客从前,如故同样的给贰个大要的目录结构,实则即为一般MySQL的优化步骤

 table 列是EXPLAIN 命令输出结果中的多少个单身行的并世无双标记符。这几个值恐怕是表名、表的别称恐怕多个为查询产生有的时候表

 2.10 ref
 ref 列能够被用来标志那么些用来张开索引相比较的列或然常量。

四、查看索引的运用意况

执行show status like ‘Handler_read%’能够看出二个值Handler_read_key,它意味着1行被索引值读的次数,倘诺值非常的低表明扩充索引得到的属性革新不高,因为索引并不平时应用。

mysql> show status like 'Handler_read%' ;
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Handler_read_first    | 3     |
| Handler_read_key      | 5     |
| Handler_read_last     | 0     |
| Handler_read_next     | 0     |
| Handler_read_prev     | 0     |
| Handler_read_rnd      | 0     |
| Handler_read_rnd_next | 20    |
+-----------------------+-------+
7 rows in set

(1)Handler_read_first:索引中率先条被读的次数。要是较高,它代表服务器正实践大气全索引围观;

(2)Handler_read_key:假使索引正在职业,这一个值代表二个行被索引值读的次数,假若值越低,表示索引得到的性质改进不高,因为索引不日常应用。

(3)Handler_read_next :遵照键顺序读下一行的请求数。倘若您用范围约束或只要施行索引围观来查询索引列,该值扩张。

(4)Handler_read_prev:依照键顺序读前一行的请求数。该读方法主要用来优化O索罗德DER BY ... DESC。

(5)Handler_read_rnd :根据固定地方读1行的伏乞数。要是您正实施大气询问并索要对结果实行排序该值较高。你或然利用了多量急需MySQL扫描整个表的询问或你的连日未有正确使用键。那些值较高,意味着运营作用低,应该树立索引来补救。

(6)Handler_read_rnd_next:在数据文件中读下壹行的伏乞数。倘使您正展开大气的表扫描,该值较高。常常表明你的表索引不正确或写入的询问未有行使索引。

   注:以上陆点来自于互联网总计,当中比较根本的五个参数是Handler_read_key与Handler_read_rnd_next。

  type: ref

  1. mysql> EXPLAIN SELECT p.*  
  2. -> FROM parent p  
  3. -> WHERE p.id NOT IN (SELECT c.parent_id FROM child  
  4. c)\G  
  5. ********************* 1. row ***********************  
  6. id: 1  
  7. select type: PRIMARY  
  8. table: p  
  9. type: ALL  
  10. possible_keys: NULL  
  11. key: NULL  
  12. key_len: NULL  
  13. ref: NULL  
  14. rows: 160  
  15. Extra: Using where  
  16. ********************* 2. row ***********************  
  17. id: 2  
  18. select_type: DEPENDENT SUBQUERY  
  19. table: c  
  20. type: index_subquery  
  21. possible_keys: parent_id  
  22. key: parent_id  
  23. key_len: 4  
  24. ref: func  
  25. rows: 1  
  26. Extra: Using index  
  27. 2 rows in set (0.00 sec)  
  28.   
  29. EXPLAIN SELECT p.* FROM parent p LEFT JOIN child c ON p.id = c.parent_id WHERE c.child_id IS NULL\G  
  30. ********************* 1. row ***********************  
  31. id: 1  
  32. select_type: SIMPLE  
  33. table: p  
  34. type: ALL  
  35. possible_keys: NULL  
  36. key: NULL  
  37. key_len: NULL  
  38. ref: NULL  
  39. rows: 160  
  40. Extra:  
  41. ********************* 2. row ***********************  
  42. id: 1  
  43. select_type: SIMPLE  
  44. table: c  
  45. type: ref  
  46. possible_keys: parent_id  
  47. key: parent_id  
  48. key_len: 4  
  49. ref: test.p.id  
  50. rows: 1  
  51. Extra: Using where; Using index; Not exists  
  52. 2 rows in set (0.00 sec) 

二、怎样高效使用索引?

  (1) 开创多列索引时,**假如查询条件中用到最左侧的列,索引一般都会被用到**

  大家创设一张未有索引的表user_1:

mysql> show create table 
user_1;
+--------+--------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                             |
+--------+--------------------------------------------------------------------------------------------------------------------------+
| user_1 | CREATE TABLE `user_1` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+--------------------------------------------------------------------------------------------------------------------------+
 1 row in set

 之后一律插入数据:

mysql> select *from user_1;
+----+----------+
| id | name     |
+----+----------+
|  1 | Zhangsan |
|  2 | Lisi     |
+----+----------+
2 rows in set

 成立多列索引index_id_name

mysql> create index index_id_name on user_1(id,name);
Query OK, 0 rows affected
Records: 0  Duplicates: 0  Warnings: 0

 实验查询explain分析name与id

mysql> explain select * from user_1 where id=1;
+----+-------------+--------+------------+------+---------------+---------------+---------+-------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+---------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | user_1 | NULL       | ref  | index_id_name | index_id_name | 5       | const |    1 |      100 | Using index |
+----+-------------+--------+------------+------+---------------+---------------+---------+-------+------+----------+-------------+
1 row in set

mysql> explain select * from user_1 where name='Lisi';
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | user_1 | NULL       | index | NULL          | index_id_name | 38      | NULL |    2 |       50 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+------+----------+--------------------------+
1 row in set

  可以看出采取最左列id的时候,rows为一,并且Extra分明使用了index,key的值为id_name_index,type的值为ref,而where不用到id,而是name的话,rows的值为2。filtered为50%,虽然key是index_id_name,但是申明是索引(个人知道,应该不太标准)

  (2) 行使like的询问,唯有%不是首先个字符并且%背后是常量的事态下,索引才也许会被选拔。

   执行explain select *from user where name like ‘%Li’后type为ALL且key的值为NULL,执行explain select *from user where name like ‘Li%’后key值不为空为index_name。

mysql> explain select*from user where name like '%Li';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set
mysql> explain select*from user where name like 'Li%';
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key        | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | range | index_name    | index_name | 9       | NULL |    1 |      100 | Using where |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-------------+
1 row in set

  (3) 若果对打客车文件进行寻觅,使用全文索引而不是用like ‘%...%’(只有MyISAM援助全文索引)。

  (4) 设若列名是索引,使用column_name is null将选用索引。

mysql> explain select*from user where name is null;
+----+-------------+-------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key        | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ref  | index_name    | index_name | 9       | const |    1 |      100 | Using where |
+----+-------------+-------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
1 row in set

mysql> explain select*from user where password
 is null;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set

 5. Using join buffer

  
以此QEP 突显没有选择任何索引(也正是全表扫描)并且管理了大气的行来满足查询。对同壹一条SELECT 语句,贰个优化过的QEP 如下所示:

4、 关于索引的优化

  Extra: Using where

  1. mysql> EXPLAIN SELECT ID, post_title  
  2. -> FROM wp_posts  
  3. -> WHERE post_type='post'  
  4. -> AND post_status='publish'  
  5. -> AND post_date > '2010-06-01';  

三、哪些状态下固然有索引也用不到?

  (1) MySQL使用MEMORY/HEAP引擎(使用的HASH索引),并且WHERE条件中不会选用”=”,in等开始展览索引列,那么不会用到目录EXPLAIN命令详解学习,常用的优化步骤。(那是有关引擎部分特点,之后会介绍)。

  (2) 用OBMWX叁分隔绝的口径,要是O冠道前面包车型客车尺度中的列有索引,而前边的列未有索引,那么涉及到的列索引不会被利用。

  试行命令show index from user能够看看password字段并未利用别的索引,而id使用了五个目录,不过where id=壹 or password='二d728480八e5111e8af7420一a06005九ce' 变成未有运用id列的primary索引与id_name_index索引

mysql> show index from user;
+-------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name      | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| user  |          0 | PRIMARY       |            1 | id          | A         |           3 | NULL     | NULL   |      | BTREE      |         |               |
| user  |          1 | index_name    |            1 | name        | A         |           3 |        2 | NULL   | YES  | BTREE      |         |               |
| user  |          1 | id_name_index |            1 | id          | A         |           3 | NULL     | NULL   |      | BTREE      |         |               |
| user  |          1 | id_name_index |            2 | name        | A         |           3 | NULL     | NULL   | YES  | BTREE      |         |               |
+-------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set

mysql> explain select*from user where id=1 or password='2d7284808e5111e8af74201a060059ce';
+----+-------------+-------+------------+------+-----------------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys         | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+-----------------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ALL  | PRIMARY,id_name_index | NULL | NULL    | NULL |    3 |    55.56 | Using where |
+----+-------------+-------+------------+------+-----------------------+------+---------+------+------+----------+-------------+
1 row in set

  (3) 不是用到复合索引中的第1列即最右边的列的话,索引就不起功能(上边已经介绍)。

  (4) 万1like是以%从头的(上边已经介绍)

  (5) 只要列类型是字符串,那么where条件中字符常量值不用’’引号引起来的话,那就不会失掉索引效果,那是因为MySQL会把输入的常量值实行转移再选择索引。

  select * from user_一 where name =250,当中name的目录为name_index,并且是varchar字符串类型,然而并未将250用引号产生’250’,那么explain之后的ref还是为NULL,rows为3

mysql> show index from user_1;
+--------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table  | Non_unique | Key_name      | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| user_1 |          1 | index_id_name |            1 | id          | A         |           2 | NULL     | NULL   | YES  | BTREE      |         |               |
| user_1 |          1 | index_id_name |            2 | name        | A         |           2 | NULL     | NULL   | YES  | BTREE      |         |               |
| user_1 |          1 | name_index    |            1 | name        | A         |           3 |        5 | NULL   | YES  | BTREE      |         |               |
+--------+------------+---------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set

mysql> explain select*from user_1 where name=250;
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | user_1 | NULL       | index | name_index    | index_id_name | 38      | NULL |    3 |    33.33 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+---------------+---------+------+------+----------+--------------------------+
1 row in set

mysql> explain select*from user_1 where name='250';
+----+-------------+--------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key        | key_len | ref   | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | user_1 | NULL       | ref  | name_index    | name_index | 18      | const |    1 |      100 | Using where |
+----+-------------+--------+------------+------+---------------+------------+---------+-------+------+----------+-------------+
1 row in set

 

  `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,

 5. Using join buffer
 那些值重申了在获取连接条件时从没接纳索引,并且供给一连缓冲区来储存中间结果。
 假诺出现了那么些值,那应该小心,依照查询的具体情况只怕须要加多索引来创新质量。

3、剖析为何SQL施行作用低------------使用explain/desc命令分析

 type: ref

 

三、 查看分析成效低的SQL

  MYSQL 5.陆.3原先只可以EXPLAIN SELECT; MYSQL五.六.三从此就能够EXPLAIN SELECT,UPDATE,DELETE,现在我们先制造3个user_table的表,之后解析select* from user where name=''语句

mysql> create table user(id int, name varchar(10),password varchar(32),primary key(id))engine=InnoDB;
Query OK, 0 rows affected

事后插入3条数据:

mysql> insert into user values(1,'Zhangsan',replace(UUID(),'-','')),(2,'Lisi',replace(UUID(),'-','')),(3,'Wangwu',replace(UUID(),'-',''));
Query OK, 3 rows affected
Records: 3  Duplicates: 0  Warnings: 0
mysql> select* from user;
+----+----------+----------------------------------+
| id | name     | password                         |
+----+----------+----------------------------------+
|  1 | Zhangsan | 2d7284808e5111e8af74201a060059ce |
|  2 | Lisi     | 2d73641c8e5111e8af74201a060059ce |
|  3 | Wangwu   | 2d73670c8e5111e8af74201a060059ce |
+----+----------+----------------------------------+
3 rows in set

上边以深入分析select*from user where name='Lisi'语句为例:

mysql> explain select*from user where name='Lisi';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set

 

下边疏解select_type等分布列的意义的:

(1)select_type:表示SELECT的类型,主要有:

  • SIMPLE:简单表,未有表连接也许子查询
  • PHavalIMA中华VY:主查询,即最外城的查询
  • UNION:UNION中的第3个或然前边的言语
  • SUBQUELacrosseY:子查询中的第四个SELECT

(二)table:结果输出的表

(三)type:表示表的连接类型,质量由好到差为:

  • system:常量表
  • const:单表中最多有1行相配,比方primary key,unique index
  • eq_ref:多表连接中使用primary key,unique index
  • ref:使用普通索引
  • ref_or_null:与ref类似,可是包涵了NULL查询
  • index_merge:索引合并优化
  • unique_subquery:in前边是3个询问主键字段的子查询
  • index_subquery:in后边是非唯一索引字段的子查询
  • range:单表中范围查看,使用like模糊查询
  • index:对于背后每1行都由此查询索引获得数码
  • all:表示全表查询

(3)possible_key:查询时恐怕选取的目录

(四)key:表示其实使用的目录

(5)key_len:索引字段的长短

(六)rows:查询时实际扫描的行数

(7)Extra:执市价况的认证和描述

(8)partitions:分区数目

(九)filtered:查询过滤的表占的比例,举例此处询问的笔录是name=Lisi的记录,占三条记下的33.3%

 ********************* 2. row ***********************

  1. ********************* 1. row ***********************  
  2.  id: 1  
  3.  select_type: SIMPLE  
  4. 缅甸新锦江赌场网址, table: p  
  5.  type: ALL  
  6.  possible_keys: NULL  
  7.  key: NULL  
  8.  key_len: NULL  
  9.  ref: NULL  
  10.  rows: 160  
  11.  Extra:  
  12. ********************* 2. row ***********************  
  13.  id: 1  
  14.  select type: SIMPLE  
  15.  table: c  
  16.  type: ref  
  17.  possible_keys: PRIMARY,parent_id  
  18.  key: parent_id  
  19.  key_len: 4  
  20.  ref: test.p.parent_id  
  21.  rows: 1  
  22.  Extra: Using where  

 | Handler_read_rnd_next | 161 |

 2.9 id
 id 列是在QEP 中展现的表的总是引用。

 key_len: 4

[sql] view plain copy print?

 那几个表的目录包涵post_type、post_status、post_date 以及ID列。上面是二个演示索引列用法的SQL 查询:

MySQL 优化器是基于成本来办事的,它并不提供别的的QEP的任务。那意味QEP 是在每条SQL 语句实践的时候动态地计
算出来的。在MySQL 存款和储蓄进度中的SQL 语句也是在每趟实践时计算QEP 的。存款和储蓄进程缓存仅仅分析查询树。

 ref: const

在那个QEP 中,大家来看选拔了多个索引,且推测唯有1行数据将被获取。**

  PRIMARY KEY (`ID`),

**

 key: parent_id

 那是UNION 语句在这之中的三个SQL 成分。

 2.11 filtered
 filtered 列给出了2个百分比的值,那个百分比率和rows 列的值一同使用,能够估算出那多少个将在和QEP 中的前3个表张开连
 接的行的多少。前叁个表正是指id 列的值比当下表的id 小的表。这一列唯有在EXPLAIN EXTENDED 语句中才会油然则生。

 | Handler_read_last | 0 |

MySQL的EXPLAIN命令用于SQL语句的询问实行布置(QEP)。那条命令的出口结果可以让大家询问MySQL 优化器是怎么试行
SQL 语句的。那条命令并从未提供任何调度提议,但它亦可提供关键的音讯帮忙你做出调优决策。

 Extra

  1. mysql> SHOW SESSION STATUS LIKE 'Handler_read%';  
  2. +--------------------------------------+---------+  
  3. | Variable_name | Value |  
  4. +--------------------------------------+---------+  
  5. | Handler_read_first | 1 |  
  6. | Handler_read_key | 164 |  
  7. | Handler_read_last | 0 |  
  8. | Handler_read_next | 107 |  
  9. | Handler_read_prev | 0 |  
  10. | Handler_read_rnd | 0 |  
  11. | Handler_read_rnd_next | 161 |  
  12. +--------------------------------------+---------+  
  13. 连锁的QEP 列还包蕴key列。  

MySQL 的EXPLAIN 语法能够运转在SELECT 语句恐怕特定表上。假使效果在表上,那么此命令等同于DESC 表命令。UPDATE

 2. Using temporary
 那些值表示使用了内部有的时候(基于内部存储器的)表。二个查询恐怕
 用到四个有时表。有众多缘故都会形成MySQL 在试行查询时期
 创设一时表。五个大规模的因由是在来自差异表的列上使用了
 DISTINCT,大概采纳了分歧的OLANDDEQX56 BY 和GROUP BY 列。
 想掌握更加的多内容能够访问_
 of_query_execution_and_use_of_temp_tables。
 能够强制内定一个一时表使用基于磁盘的MyISAM 存款和储蓄引
 擎。那样做的因由根本有七个:
  内部有时表占用的空中中国足球球社团一流联赛过min(tmp_table_size,max_
 heap_table_size)系统变量的限定
  使用了TEXT/BLOB 列

 为查询明确QEP 的快慢也会潜移默化到查询的习性。假诺开掘有大批量的只怕的目录,则代表这么些索引未有被选择到。

 3. Using filesort
 那是O汉兰达DELX570 BY 语句的结果。那只怕是二个CPU 密集型的经过。
 能够通过挑选适宜的目录来改善质量,用索引来为查询结果排序。详细进度请参见第6章。

 能够行使SHOW STATUS 命令来查阅实际的行操作。那一个命令能够提供最好的认同物理行操作的不二诀要。请看上边包车型客车示范:

 2.7  partitions
  partitions 列代表给定表所利用的分区。那一列只会在EXPLAIN
  PARTITIONS 语句中冒出。

 table: c

 
 2.3 possible_keys
 possible_keys 列建议优化器为查询选定的目录。
 四个会列出大气或许的目录(举个例子多于叁 个)的QEP 意味着备选索引数量太多了,同时也大概提醒存在贰个失效的单列索引。
 能够用第3 章详细介绍过的SHOW INDEXES 命令来检查索引是不是可行且是或不是具备非常的基数。
 为查询鲜明QEP 的快慢也会潜移默化到查询的习性。假设开采有大量的恐怕的目录,则象征那一个索引未有被应用到。
 相关的QEP 列还蕴涵key 列。
 
 2.4 key_len
 key_len 列定义了用来SQL 语句的接连条件的键的长短。此列值对于确认索引的可行以及多列索引中用到的列的数码很重大。
 此列的片段示例值如下所示:
 
 此列的一对示例值如下所示:
 key_len: 4 // INT NOT NULL
 key_len: 5 // INT NULL
 key_len: 30 // CHAR(30) NOT NULL
 key_len: 32 // VARCHAR(30) NOT NULL
 key_len: 92 // VARCHAR(30) NULL CHARSET=utf8
 
 从那几个示例中得以看到,是不是足感觉空、可变长度的列以及key_len 列的值只和用在延续和WHERE 条件中的索引的列
 有关。索引中的别的列会在O奥迪Q3DE汉兰达 BY 也许GROUP BY 语句中被用到。上面那几个来自于盛名的开源博客软件WordPress 的表展现了
 怎样以最好艺术选取带有定义好的表索引的SQL 语句:
**

 key: NULL

**

 key_len: NULL

 1. SIMPLE
 对于不包罗子查询和别的复杂语法的归纳询问,这是叁个常 见的项目。

 

[sql] view plain copy print?

 ref: const

 table: c

[sql] view plain copy print?

 table: p

**

  possible_keys: NULL

 7. Select tables optimized away
 这一个值意味着仅通过选择索引,优化器恐怕仅从聚合函数结实中回到一行。请看上面包车型地铁以身作则:

  rows: 1

2.2 ROWS
 rows 列提供了试图剖判全部存在于累计结果聚焦的行数目标MySQL 优化器估摸值。QEP 很轻松描述这几个很不便的总计量。
 查询中总的读操作数量是基于统一以前行的每一行的rows 值的一连储存而得出的。那是一种嵌套行算法。
 
 以几次三番五个表的QEP 为例。通过id=一 这几个规格找到的首先行的rows 值为一,那等于对首个表做了三遍读操作。第三行是
 通过id=二 找到的,rows 的值为五。那等于有伍 次读操作符合当下一的积存量。参照他事他说加以侦查八个表,读操作的总的数量量是6。在另二个QEP
 中,第一rows 的值是五,第一rows 的值是①。那也正是第二个表有4次读操作,对四个积存量中各种都有二个读操作。因而七个表
 总的读操作的次数是10(5+五)次。
 
 最佳的估计值是壹,一般的话这种情形产生在当搜索的行在表中得以经过主键或许唯一键找到的时候。
 在底下的QEP 中,外面包车型地铁嵌套循环能够经过id=一来找到,其估价的大意行数是1。第壹个巡回处理了十行。  

 那个值重点重申了只须求利用索引就能够满意查询表的要求,无需一直访问表数据。请参考第5章的详实示例来明白那

 8. Distinct
 这些值意味着MySQL 在找到第三个卓殊的行之后就能停下寻觅其余行。

 此列的一部分示例值如下所示:

[sql] view plain copy print?

 -> AND post_status='publish'

 
 通过SHOW STATUS 命令能够查阅实际的行操作,该命令声明物理读操作数量大幅度增添。请看上边包车型大巴言传身教:
**

  type: ALL

[sql] view plain copy print?

  | Variable_name         | Value |

[sql] view plain copy print?

 能够经过甄选适合的目录来立异质量,用索引来为查询结果排序。详细经过请仿照效法第陆章。

 9. Index merges
 当MySQL 决定要在3个加以的表上使用超越一个目录的时候,就能够产出以下格式中的三个,详细表明使用的目录以及联合的品种。
  Using sort_union(...)
  Using union(...)
  Using intersect(...)

 

 那些表的目录包含post_type、post_status、post_date 以及ID列。上面是3个演示索引列用法的SQL 查询:
 EXPLAIN SELECT ID, post_title FROM wp_posts WHERE post_type='post' AND post_date > '2010-06-01';
 
 这么些查询的QEP 重临的key_len 是6二。那注脚唯有post_type列上的索引用到了(因为(20×三)+贰=62)。就算查询在WHERE 语句
 中使用了post_type 和post_date 列,但只有post_type 部分被用到了。其余索引未有被选取的来由是MySQL 只可以使用定义索引的
 最左侧部分。为了越来越好地动用那么些目录,能够修改这几个查询来调节目录的列。请看上面包车型客车示范:

 中,第二rows 的值是5,第一rows 的值是一。这也正是第贰个表有8回读操作,对多少个累积量中各样都有一个读操作。由此多个表

[sql] view plain copy print?

  type: ALL

[sql] view plain copy print?

 select type: PRIMARY

 能够利用SHOW STATUS 命令来查看实际的行操作。这一个命令能够提供最好的分明物理行操作的点子。请看上边包车型大巴躬体力行:
**

MySQL EXPLAIN命令可感到SQL语句中的各种表生成以下音信:

  1. ********************* 1. row ***********************  
  2. id: 1  
  3. select_type: SIMPLE  
  4. table: p  
  5. type: const  
  6. possible_keys: PRIMARY  
  7. key: PRIMARY  
  8. key_len: 4  
  9. ref: const  
  10. rows: 1  
  11. Extra:  
  12. ********************* 2. row ***********************  
  13. id: 1  
  14. select_type: SIMPLE  
  15. table: c  
  16. type: ref  
  17. possible_keys: parent_id  
  18. key: parent_id  
  19. key_len: 4  
  20. ref: const  
  21. rows: 10  
  22. Extra:  

 key_len: 4

**

 rows: 1

MySQL EXPLAIN 命令详解

  

[sql] view plain copy print?

 -> SELECT p.* FROM parent p WHERE p.id > 5;

**

MySQL 优化器是依赖费用来办事的,它并不提供其余的QEP的职责。这意味着QEP 是在每条SQL 语句推行的时候动态地计

QEP 中各样行的具备列表如下所示:  id
 select_type
 table
 partitions(那1列唯有在EXPLAIN PARTITIONS 语法中才会油不过生)
 possible_keys
 key
 key_len
 ref
 rows
 filtered(那壹列只有在EXPLAINED EXTENDED 语法中才会冒出)
 Extra

 rows

那个列体现了SELECT 语句对每叁个表的QEP。八个表大概和2个物理格局表恐怕在SQL 实践时生成的内部有的时候表(比方从子查询或许统一操作会产生内部有的时候表)相关联。
能够参照MySQL Reference 马努al 获得越多音讯:。

 ) DEFAULT CHARSET=utf8

 4. DEPENDENT SUBQUERY
 那个select-type 值是为使用子查询而定义的。下边包车型地铁SQL语句提供了这些值:
 mysql> EXPLAIN SELECT p.*
 -> FROM parent p
 -> WHERE p.id NOT IN (SELECT c.parent_id FROM child c);
 
 5. UNION
 那是UNION 语句个中的七个SQL 成分。
 6. UNION RESULT
 那是1多元概念在UNION 语句中的表的归来结果。当select_type 为这几个值时,日常能够看看table 的值是<unionN,M>,
 那表明相称的id 行是其壹集结的一局地。上边包车型客车SQL发生了3个UNION和UNION RESULT select-type:
 mysql> EXPLAIN SELECT p.* FROM parent p WHERE p.val
 LIKE 'a%'
 -> UNION
 -> SELECT p.* FROM parent p WHERE p.id > 5;

 2.11 filtered

二 各列详解
MySQL EXPLAIN命令可感到SQL语句中的每种表生成以下音信:

  +-----------------------+-------+

在5.6.拾版本里面,是足以平素对dml语句进行explain剖判操作的.

SET col1 = X, col2 = Y

  1. SELECT col1, col2  
  2. FROM table1  
  3. WHERE id1 = 9  
  4. AND dt >= '2010-01-01';  

 rows: 160

**

 2.9 id

 2.6 select_type
 select_type 列提供了各类表示table 列引用的采取方法的类别。最布满的值包含SIMPLE、POdysseyIMAPRADOY、DEPAJEROIVED 和UNION。别的或者
 的值还有UNION RESULT、DEPENDENT SUBQUE科雷傲Y、DEPENDENT UNION、UNCACHEABLE UNION 以及UNCACHEABLE QUE昂科威Y。

 key: NULL

  
 在下一个QEP 中,通过id=1找到的外围嵌套循环猜测有160行。第2个巡回测度有一 行。
**

 在下1个QEP 中,通过id=1找到的外层嵌套循环推测有160行。第三个循环算计有一 行。

 2.12 type
 type 列代表QEP 中钦定的表使用的接连形式。下边是最常用的两种连接方式:
  const 当这几个表最五唯有一行相配的行时出现system 那是const 的特例,当表唯有1个row 时会出现
  eq_ref 那个值表示有1行是为了每一种从前鲜明的表而读取的
  ref 那么些值表示全体具备极度的索引值的行都被用到
  range 这些值表示具备符合1个给定范围值的索引行都被用到
  ALL 那个值表示供给一次全表扫描别的品种的值还有fulltext 、ref_or_null 、index_merge 、unique_subquery、index_subquery 以及index。
  想打听越来越多音讯方可访问。  

 key_len: 30 // CHAR(30) NOT NULL

  1. UPDATE table1  
  2. SET col1 = X, col2 = Y  
  3. WHERE id1 = 9  
  4. AND dt >= '2010-01-01';  

 额外音讯。Extra 列能够包括多少个值,能够有过多例外的取值,并

1 语法
MySQL 的EXPLAIN 语法能够运维在SELECT 语句大概特定表上。尽管效果在表上,那么此命令等同于DESC 表命令。UPDATE
和DELETE 命令也亟需开始展览品质创新,当这几个命令不是一向在表的主码上运营时,为了确认保障最优化的目录使用率,需求把它们改
写成SELECT 语句(以便对它们实施EXPLAIN 命令)。请看上边包车型客车示范:

 精通你的应用程序(包蕴技能和兑现只怕性)和优化SQL 语句同等首要。上面给出二个从父亲和儿子关系中拿走孤立的四叔记录的商

 三 解释EXPLAIN 输出结果
 掌握你的应用程序(包含技艺和完结可能性)和优化SQL 语句同等主要。上边给出二个从老爹和儿子关系中获得孤立的公公记录的商
 业供给的例证。这一个查询能够用三种分裂的主意组织。纵然会发出一样的结果,但QEP 会呈现三种区别的路径。

 key_len 列定义了用来SQL 语句的连年条件的键的长度。此列值对于确认索引的灵光以及多列索引中用到的列的数量很首要。

[sql] view plain copy print?

  `post_type` varchar(20) NOT NULL DEFAULT 'post',

[sql] view plain copy print?

 EXPLAIN SELECT ID, post_title FROM wp_posts WHERE post_type='post' AND post_date > '2010-06-01';

  1. ********************* 1. row ***********************  
  2. id: 1  
  3. select_type: SIMPLE  
  4. table: inventory  
  5. type: ref  
  6. possible_keys: item_id  
  7. key: item_id  
  8. key_len: 4  
  9. ref: const  
  10. rows: 1  
  11. Extra:  

  Using intersect(...)

 这些值意味着MySQL 在找到第三个门Doug外的行之后就能够截止找出其余行。

  key: parent_id

  select_type: SIMPLE

 ********************* 2. row ***********************

 id

  key: item_id

 | Handler_read_prev | 0 |

EXPLAIN命令详解学习 MySQL的EXPLAIN命令用于SQL语句的询问实行安插(QEP)。那条命令的出口结果能够让我们询问MySQL 优化器是怎么着推行 SQL 语...

 key: parent_id

 

 3. Using filesort

 table: p

 4. Using index

 这申明相称的id 行是其一集结的一部分。上边包车型大巴SQL发生了贰个UNION和UNION RESULT select-type:

 select_type

2.1 key

 2.8 Extra

 id: 1

 mysql> EXPLAIN SELECT p.* FROM parent p WHERE p.val

 通过id=二 找到的,rows 的值为伍。那相当于有伍 次读操作符合当下1的储存量。参照他事他说加以侦察多少个表,读操作的总量量是六。在另贰个QEP

  Extra:

  KEY `type_status_date`(`post_type`,`post_status`,`post_date`,`ID`)

  内部不常表占用的空间超越min(tmp_table_size,max_

 possible_keys: PRIMARY

  select_type: SIMPLE

 的标志符,如派生表、子查询或集结。上边是QEP 中table 列的有的示范:

 key_len: 32 // VARCHAR(30) NOT NULL

  id: 1

 2. Using temporary

 table: item

 ref: test.p.id

  PRIMARY KEY (`ID`),

 全表扫描。倘使也选拔了目录,那么行的界定标准是透过获得必

 type: index_subquery

 mysql> EXPLAIN SELECT p.*

 partitions(那壹列唯有在EXPLAIN PARTITIONS 语法中才会冒出)

 ref

 ********************* 2. row ***********************

  id: 1

  ********************* 1. row ***********************

 key_len: NULL

UPDATE table1

 key

  possible_keys: NULL

 接的行的数据。前两个表正是指id 列的值比当下表的id 小的表。那一列唯有在EXPLAIN EXTENDED 语句中才会现出。

 

 

 要的多少以往处理读缓冲区来贯彻的。

 ref: NULL

  | Handler_read_prev     | 0     |

 mysql> SHOW SESSION STATUS LIKE 'Handler_read%';

首页 | 关于我们 | 产品中心  | 新闻中心 | 资质认证  | 下载中心 | 在线留言  | 联系我们
Copyright © 2014 缅甸新锦江赌场-官方网站缅甸新锦江 Rights Reserved.  技术支持:温州中网   备案号:浙ICP备14009337号-1  

Baidu
sogou