GVKun编程网logo

MySQL 性能分析及 explain 的使用(mysql性能分析语句)

2

在本文中,您将会了解到关于MySQL性能分析及explain的使用的新资讯,同时我们还将为您解释mysql性能分析语句的相关在本文中,我们将带你探索MySQL性能分析及explain的使用的奥秘,分析

在本文中,您将会了解到关于MySQL 性能分析及 explain 的使用的新资讯,同时我们还将为您解释mysql性能分析语句的相关在本文中,我们将带你探索MySQL 性能分析及 explain 的使用的奥秘,分析mysql性能分析语句的特点,并给出一些关于1、查看操作系统 2、查看命令帮助的几种方式 3、pwd 的使用 4、mkdir 的使用、3.Mysql-Explain、dialog 的使用 包括 FLAG_DIM_BEHIND 和 dimAmount 的使用、Explain 的使用--《MySQL性能调优与架构设计》节选的实用技巧。

本文目录一览:

MySQL 性能分析及 explain 的使用(mysql性能分析语句)

MySQL 性能分析及 explain 的使用(mysql性能分析语句)

MySQL 性能分析 explain 用法的知识是本文我们主要要介绍的内容,接下来就让我们通过一些实际的例子来介绍这一过程,希望能够对您有所帮助。

explain 显示了 mysql 如何使用索引来处理 select 语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。

使用方法,在 select 语句前加上 explain 就可以了,如:

explain select * from statuses_status where id=11;

explain 列的解释
table:显示这一行的数据是关于哪张表的

type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为 const、eq_reg、ref、range、indexhe 和 all

possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从 where 语句中选择一个合适的语句

key: 实际使用的索引。如果为 null,则没有使用索引。很少的情况下,mysql 会选择优化不足的索引。这种情况下,可以在 select 语句中使用 use index(indexname)来强制使用一个索引或者用 ignore index(indexname)来强制 mysql 忽略索引

key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数

rows:mysql 认为必须检查的用来返回请求数据的行数

extra:关于 mysql 如何解析查询的额外信息。将在表 4.3 中讨论,但这里可以看到的坏的例子是 using temporary 和 using filesort,意思 mysql 根本不能使用索引,结果是检索会很慢


extra 列返回的描述的意义

distinct: 一旦 mysql 找到了与行相联合匹配的行,就不再搜索了

not exists: mysql 优化了 left join,一旦它找到了匹配 left join 标准的行,就不再搜索了

range checked for each record(index map:#): 没有找到理想的索引,因此对于从前面表中来的每一个行组合,mysql 检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一

using filesort: 看到这个的时候,查询就需要优化了。mysql 需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行

using index: 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候

using temporary 看到这个的时候,查询需要优化了。这里,mysql 需要创建一个临时表来存储结果,这通常发生在对不同的列集进行 order by 上,而不是 group by 上

where used 使用了 where 从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型 all 或 index,这就会发生,或者是查询有问题不同连接类型的解释(按照效率高低的顺序排序)

system 表只有一行:system 表。这是 const 连接类型的特殊情况

const: 表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为 mysql 先读这个值然后把它当做常数来对待

eq_ref: 在连接中,mysql 在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用

ref: 这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少 — 越少越好

range: 这个连接类型使用索引返回一个范围中的行,比如使用 > 或 < 查找东西时发生的情况

index: 这个连接类型对前面的表中的每一个记录联合进行完全扫描(比 all 更好,因为索引一般小于表数据)

all: 这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免

1. 使用 explain 语句去查看分析结果

如 explain select * from test1 where id=1; 会出现:id  selecttype  table  type possible_keys  key key_len  ref rows  extra 各列。

其中,

type=const 表示通过索引一次就找到了;

key=primary 的话,表示使用了主键;

type=all, 表示为全表扫描;

key=null 表示没用到索引。type=ref, 因为这时认为是多个匹配行,在联合查询中,一般为 REF。

2.MYSQL 中的组合索引

假设表有 id,key1,key2,key3, 把三者形成一个组合索引,则

如:

where key1=....     
where key1=1 and key2=2     
where key1=3 and key3=3 and key2=2

根据最左原则,这些都是可以使用索引的,如 from test where key1=1 order by key3,用 explain 分析的话,只用到了 normal_key 索引,但只对 where 子句起作用,而后面的 order by 需要排序。

3. 使用慢查询分析

在 my.ini 中:

long_query_time=1

log-slow-queries=d:\mysql5\logs\mysqlslow.log

把超过 1 秒的记录在慢查询日志中

可以用 mysqlsla 来分析之。也可以在 mysqlreport 中,有如

DMS 分别分析了 select ,update,insert,delete,replace 等所占的百份比

4.MYISAM 和 INNODB 的锁定

myisam 中,注意是表锁来的,比如在多个 UPDATE 操作后,再 SELECT 时,会发现 SELECT 操作被锁定了,必须等所有 UPDATE 操作完毕后,再能 SELECT

innodb 的话则不同了,用的是行锁,不存在上面问题。

5.MYSQL 的事务配置项

innodb_flush_log_at_trx_commit=1

表示事务提交时立即把事务日志写入磁盘,同时数据和索引也更新。

innodb_flush_log_at_trx_commit=0

事务提交时,不立即把事务日志写入磁盘,每隔 1 秒写一次

innodb_flush_log_at_trx_commit=2

事务提交时,立即写入磁盘文件(这里只是写入到内核缓冲区,但不立即刷新到磁盘,而是每隔 1 秒刷新到盘,同时更新数据和索引

explain 用法

EXPLAIN tbl_name 或:EXPLAIN [EXTENDED] SELECT select_options

前者可以得出一个表的字段结构等等,后者主要是给出相关的一些索引信息,而今天要讲述的重点是后者。

举例

mysql> explain select * from event;  
+—-+————-+——-+——+—————+——+———+——+——+——-+  
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |  
+—-+————-+——-+——+—————+——+———+——+——+——-+  
| 1 | SIMPLE | event | ALL | NULL | NULL | NULL | NULL | 13 | |  
+—-+————-+——-+——+—————+——+———+——+——+——-+  
1 row in set (0.00 sec)

各个属性的含义

id

select 查询的序列号

select_type

select 查询的类型,主要是区别普通查询和联合查询、子查询之类的复杂查询。

table

输出的行所引用的表。

type

联合查询所使用的类型。

type 显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

一般来说,得保证查询至少达到 range 级别,最好能达到 ref。

possible_keys

指出 MySQL 能使用哪个索引在该表中找到行。如果是空的,没有相关的索引。这时要提高性能,可通过检验 WHERE 子句,看是否引用某些字段,或者检查字段不是适合索引。

key

显示 MySQL 实际决定使用的键。如果没有索引被选择,键是 NULL。

key_len

显示 MySQL 决定使用的键长度。如果键是 NULL,长度就是 NULL。文档提示特别注意这个值可以得出一个多重主键里 mysql 实际使用了哪一部分。

ref

显示哪个字段或常数与 key 一起被使用。

rows

这个数表示 mysql 要遍历多少数据才能找到,在 innodb 上是不准确的。

Extra

如果是 Only index,这意味着信息只用索引树中的信息检索出的,这比扫描整个表要快。

如果是 where used,就是使用上了 where 限制。

如果是 impossible where 表示用不着 where,一般就是没查出来啥。

如果此信息显示 Using filesort 或者 Using temporary 的话会很吃力,WHERE 和 ORDER BY 的索引经常无法兼顾,如果按照 WHERE 来确定索引,那么在 ORDER BY 时,就必然会引起 Using filesort,这就要看是先过滤再排序划算,还是先排序再过滤划算。

关于 MySQL 性能分析及 explain 用法的知识就介绍到这里了,希望本次的介绍能够对您有所收获!


1、查看操作系统 2、查看命令帮助的几种方式 3、pwd 的使用 4、mkdir 的使用

1、查看操作系统 2、查看命令帮助的几种方式 3、pwd 的使用 4、mkdir 的使用

1、如何查看操作系统

1.1[root@VM_86_3_centos zhanghao]# uname -m(32and64)
x86_64

1.2[root@VM_86_3_centos zhanghoc]# uname -a
Linux VM_86_3_centos 3.10.0-514.26.2.el7.x86_64 #1 SMP Tue Jul 4 15:04:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

1.3[root@VM_86_3_centos zhanghao]# ls -ld /lib64
lrwxrwxrwx. 1 root root 9 Apr 21 2016 /lib64 -> usr/lib64

1.4 [root@VM_86_3_centos zhanghao]# cat /etc/redhat-release (版本)
CentOS Linux release 7.2.1511 (Core)

1.5 [root@VM_86_3_centos zhanghao]# uname -r(内核)
3.10.0-514.26.2.el7.x86_64

 

2. 查看命令的几种方法

2.1 [命令] --help 适用于一般命令,非内置命令

2.2 man [命令]  适用于一般命令,非内置命令

2.3 help  [命令] 适用于内置命令

3、pwd 的使用

[root@VM_86_3_centos /]# help pwd
pwd: pwd [-LP]
Print the name of the current working directory.(打印当前工作目录的名称)

Options:(备选文案、此处为选项)
-L print the value of $PWD if it names the current working (打印 pwd 的值,如果它命名当前工作)
directory(目录)
-P print the physical directory, without any symbolic links(打印物理录,不带任何符号链接)

By default, `pwd'' behaves as if`-L'' were specified.(默认情况下,“pwd” 的行为就像指定了 “-l” 一样)

Exit Status:(退出状态)
Returns 0 unless an invalid option is given or the current directory(除非给定无效选项或当前目录,否则返回 0)
cannot be read.(无法读取)

[root@VM_86_3_centos /]# echo $PWD
/
[root@VM_86_3_centos /]# pwd -L
/
[root@VM_86_3_centos /]# pwd
/
[root@VM_86_3_centos /]# cd /etc/init.d/
[root@VM_86_3_centos init.d]# pwd
/etc/init.d
[root@VM_86_3_centos init.d]# pwd -L
/etc/init.d
[root@VM_86_3_centos init.d]# pwd -P
/etc/rc.d/init.d

 

4、mkdir 的使用

-m, --mode=MODE set file mode (as in chmod), not a=rwx - umask
-p, --parents no error if existing, make parent directories as needed
-v, --verbose print a message for each created directory

[root@VM_86_3_centos ~]# mkdir test/a/b
mkdir: cannot create directory ‘test/a/b’: No such file or directory
[root@VM_86_3_centos ~]# mkdir -p test/a/b
[root@VM_86_3_centos ~]# tree test
-bash: tree: command not found
[root@VM_86_3_centos ~]# mkdir -pv test/a/b/c/d/e
mkdir: created directory ‘test/a/b/c’
mkdir: created directory ‘test/a/b/c/d’
mkdir: created directory ‘test/a/b/c/d/e’

创建有规律的多目录(此处数字为文件名)

[root@VM_86_3_centos ~]# echo 1 2 3 4
1 2 3 4
[root@VM_86_3_centos ~]# echo {1..10}
1 2 3 4 5 6 7 8 9 10

[root@VM_86_3_centos ~]# mkdir -pv test/ {1..3}/{4..6}
mkdir: created directory ‘1/5’
mkdir: created directory ‘1/6’
mkdir: created directory ‘2/5’
mkdir: created directory ‘2/6’
mkdir: created directory ‘3/5’
mkdir: created directory ‘3/6’

 

3.Mysql-Explain

3.Mysql-Explain

1.是什么(查看执行计划)

使用EXPLAIN关键字可以模拟优化器执行SQL语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是结构的性能瓶颈

2.能干嘛

表的读取顺序 数据读取操作的操作类型 哪些索引可以使用 哪些索引被实际使用 表之间的引用 每张表有多少行被优化器查询

3.怎么玩

Explain+SQL语句 执行计划包含的信息

4.各个字段解释

4.1 id

select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序

三种情况 ​:

  id相同,执行顺序由上至下

  id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

     id相同不同,同时存在.id相同的被认为是同一组,自上而下执行,所有id中,id越大优先级越高,优先被执行

 

 4.2 select_type

  select_type 有哪些.查询的类型,主要用于区别

  普通查询、联合查询、子查询等的复杂查询

    1.SIMPLE 简单的select查询,查询中不包含子查询或者UNION

    2.PRIMARY 查询中若包含任何复杂的子部分,最外层查询则被标记为(子查询中最外层查询)

    3.SUBQUERY 在SELECT或者WHERE列表中包含了子查询(子查询内层第一个SELECT,结果不依赖于外部查询)

    4.DERIVED 在FROM列表中包含的子查询被标记为DERIVED(衍生) MySQL会递归执行这些子查询,把结果放在临时表里。

​    5.UNION 若第二个SELECT出现在UNION之后,则被标记为UNION; 若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED

   6.UNION RESULT 从UNION表获取结果的SELECT(UNION 中合并结果)

4.3 table 显示这一行的数据是关于哪张表的

4.4 type 访问类型排列

system>const>eq_ref>ref>fulltext>ref_of_null>index_merge>unique_subquery>index_subquery>range>index>ALL

显示查询使用了何种类型 从最好到最差依次是: system>const>eq_ref>ref>range>index>ALL

system 表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,这个也可以忽略不计

const 表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快。如将主键至于where列表中,MySQL就能将该查询转换为一个常量

eq_ref 唯一性索引,对于每个索引键,表中只有一条记录与之匹配,常见于主键或唯一索引扫描

 

ref 非唯一索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体

 

range 只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引一般就是在你的where语句中出现了between、<、>、in等的查询这种范围扫描索引扫描比全表扫描要好,因为他只需要开始索引的  某一点,而结束语另一点,不用扫描全部索引

 

index Full Index Scan,index与ALL区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘中读的

 

all FullTable Scan,将遍历全表以找到匹配的行

备注: 一般来说,得保证查询只是达到range级别,最好达到ref

4.5 possible_keys

显示可能应用在这张表中的索引,一个或多个。(该查询可以利用的索引,如果没有任何索引显示 null) 查询涉及的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用

 4.6 key

实际使用的索引。如果为null则没有使用索引(Mysql 从 Possible_keys 所选择使用索引) 查询中若使用了覆盖索引,则该索引仅出现在key列表中

4.7 key_len

 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好

 key_len显示的值为索引最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的

 

4.8 ref

 显示索引那一列被使用了,如果可能的话,是一个常数。那些列或常量被用于查找索引列上的值

4.9  rows

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

4.10 Extra

包含不适合在其他列中显示但十分重要的额外信息

1.Using filesort

  说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。 MySQL中无法利用索引完成排序操作成为“文件排序”(当Query中包含 ORDER BY 操作,而且无法利用索引完成排序)

 

2.Using temporary

  使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序order by 和分组查询 group by,如果使用到的话竟可能的将排序的字段列和索引的列字段和顺序均保持一致(某些操作必须使用临时表,常见 GROUP BY ; ORDER BY)

3.USING index

   表示相应的select操作中使用了覆盖索引(Coveing Index),避免访问了表的数据行,效率不错! 如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有同时出现using where,表明索引用来读取数据而非执行查找动作。

4.Using where

   表面使用了where过滤(不用读取表中所有信息,仅通过索引就可以获取所需数据;)

5.using join buffer

  使用了连接缓存

6.impossible where

   where子句的值总是false,不能用来获取任何元组

explain select * from tbl_emp where name=''july'' and name=''wxt'';

7.select tables optimized away

  在没有GROUPBY子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。 8.distinct

  优化distinct,在找到第一匹配的元组后即停止找同样值的工作

覆盖索引(Covering Index)

覆盖索引,一般也叫索引覆盖

理解方式1:就是select 的数据列只用从索引中就能获得,不必读取数据行。mysql 可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件,换句话说:查询列要被所创建的索引覆盖

理解方式2:索引是高效找到行的一个方法,但是一般数据库也能使用索引找到一个列的数据,因此就不必读取整个行。毕竟索引叶子节点存储了他们索引的数据。当然能通过读取索引就可以得到想要的数据。那么久不需要读取行了,一个索引包含了(或者覆盖了)满足查询结果的数据就叫做覆盖索引

注意:如果要使用覆盖索引,一定要注意select 列表中只取出需要的列,不可select *. 因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降

 

dialog 的使用 包括 FLAG_DIM_BEHIND 和 dimAmount 的使用

dialog 的使用 包括 FLAG_DIM_BEHIND 和 dimAmount 的使用

首先自定义一个类,j 继承自 dialog 类。

设置透明度,主要设置的是 dialog 自身的透明度

WindowManager.LayoutParams lp=dialog.getWindow().getAttributes();
                lp.alpha=1.0f;
                dialog.getWindow().setAttributes(lp);

alpha 在 0.0f 到 1.0f 之间。1.0 完全不透明,0.0f 完全透明,自身不可见。

设置幕布,也就是本 dialog 的背景层。

dialog.setContentView(R.layout.dialog);
WindowManager.LayoutParams lp=dialog.getWindow().getAttributes();
lp.dimAmount=1.0f;
dialog.getWindow().setAttributes(lp);
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

dimAmount 在 0.0f 和 1.0f 之间,0.0f 完全不暗,即背景是可见的 ,1.0f 时候,背景全部变黑暗。

如果要达到背景全部变暗的效果,需要设置  dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
,否则,背景无效果。


此方法可以用来设置浮动层。呵呵!

Explain 的使用--《MySQL性能调优与架构设计》节选

Explain 的使用--《MySQL性能调优与架构设计》节选

Explain 的使用(1)

说到Explain,肯定很多读者之前已经用过了,MySQL Query Optimizer 通过执行 EXPLAIN 命令来告诉我们它将使用一个怎样的执行计划来优化Query。所以,可以说 Explain 是在优化 Query 时最直接有效地验证我们想法的工具。在本章前面已经谈到,一个好的 SQL Performance Tuner 在动手优化一个 Query 之前,头脑中就应该已经有了一个好的执行计划,后面的优化工作只是为实现该执行计划而作出的各种调整。

在对某个 Query 优化过程中,须要不断地使用 Explain 来验证各种调整是否有效。就像前面很多示例都会通过 Explain 来验证和展示结果一样,所有的 Query 优化都应该充分利用它。

下面看一下在 MySQL Explain功能中展示各种信息的解释。

ID:MySQL Query Optimizer选定的执行计划中查询的序列号。

Select_type:所使用的查询类型,主要有以下这几种查询类型。

DEPENDENT SUBQUERY:子查询内层的第一个SELECT,依赖于外部查询的结果集。

DEPENDENT UNION:子查询中的UNION,且为UNION中从第二个SELECT开始的后面所有SELECT,同样依赖于外部查询的结果集。

PRIMARY:子查询中的最外层查询,注意并不是主键查询。

SIMPLE:除子查询或UNION之外的其他查询。

SUBQUERY:子查询内层查询的第一个SELECT,结果不依赖于外部查询结果集。

UNCACHEABLE SUBQUERY:结果集无法缓存的子查询。

UNION:UNION语句中第二个SELECT开始后面的所有SELECT,第一个SELECT为PRIMARY。

UNION RESULT:UNION 中的合并结果。

Table:显示这一步所访问的数据库中的表的名称。

Type:告诉我们对表使用的访问方式,主要包含如下集中类型。

all:全表扫描。

const:读常量,最多只会有一条记录匹配,由于是常量,实际上只须要读一次。

eq_ref:最多只会有一条匹配结果,一般是通过主键或唯一键索引来访问。

fulltext:进行全文索引检索。

index:全索引扫描。

index_merge:查询中同时使用两个(或更多)索引,然后对索引结果进行合并(merge),再读取表数据。

index_subquery:子查询中的返回结果字段组合是一个索引(或索引组合),但不是一个主键或唯一索引。

rang:索引范围扫描。

ref:Join语句中被驱动表索引引用的查询。

ref_or_null:与ref的唯一区别就是在使用索引引用的查询之外再增加一个空值的查询。

system:系统表,表中只有一行数据;

unique_subquery:子查询中的返回结果字段组合是主键或唯一约束。

Possible_keys:该查询可以利用的索引。如果没有任何索引可以使用,就会显示成null,这项内容对优化索引时的调整非常重要。

Key:MySQL Query Optimizer 从 possible_keys 中所选择使用的索引。

Key_len:被选中使用索引的索引键长度。

Ref:列出是通过常量(const),还是某个表的某个字段(如果是join)来过滤(通过key)的。

Rows:MySQL Query Optimizer 通过系统收集的统计信息估算出来的结果集记录条数。

Extra:查询中每一步实现的额外细节信息,主要会是以下内容。

Distinct:查找distinct 值,当mysql找到了第一条匹配的结果时,将停止该值的查询,转为后面其他值查询。

Full scan on NULL key:子查询中的一种优化方式,主要在遇到无法通过索引访问null值的使用。

Impossible WHERE noticed after reading const tables:MySQL Query Optimizer 通过收集到的统计信息判断出不可能存在结果。

No tables:Query 语句中使用 FROM DUAL或不包含任何 FROM子句。

Not exists:在某些左连接中,MySQL Query Optimizer通过改变原有 Query 的组成而使用的优化方法,可以部分减少数据访问次数。

Explain 的使用(2)

Range checked for each record (index map: N):通过 MySQL 官方手册的描述,当 MySQL Query Optimizer 没有发现好的可以使用的索引时,如果发现前面表的列值已知,部分索引可以使用。对前面表的每个行组合,MySQL检查是否可以使用range或index_merge访问方法来索取行。

SELECT tables optimized away:当我们使用某些聚合函数来访问存在索引的某个字段时,MySQL Query Optimizer 会通过索引直接一次定位到所需的数据行完成整个查询。当然,前提是在 Query 中不能有 GROUP BY 操作。如使用MIN()或MAX()的时候。

Using filesort:当Query 中包含 ORDER BY 操作,而且无法利用索引完成排序操作的时候,MySQL Query Optimizer 不得不选择相应的排序算法来实现。

Using index:所需数据只需在 Index 即可全部获得,不须要再到表中取数据。

Using index for group-by:数据访问和 Using index 一样,所需数据只须要读取索引,当Query 中使用GROUP BY或DISTINCT 子句时,如果分组字段也在索引中,Extra中的信息就会是 Using index for group-by。

Using temporary:当 MySQL 在某些操作中必须使用临时表时,在 Extra 信息中就会出现Using temporary 。主要常见于 GROUP BY 和 ORDER BY 等操作中。

Using where:如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则会出现 Using where 信息。

Using where with pushed condition:这是一个仅仅在 NDBCluster存储引擎中才会出现的信息,而且还须要通过打开 Condition Pushdown 优化功能才可能被使用。控制参数为 engine_condition_pushdown 。

这里通过分析示例来看一下不同的 Query 语句通过 Explain 所显示的不同信息。

先看一个简单的单表 Query,如示例代码8-4所示:

代码8-4

sky@localhost : example 11:33:18> EXPLAIN SELECT COUNT(*),MAX(id),MIN(id)    
    -> FROM user\G   
*************************** 1. row ***************************   
             id: 1   
      select_type: SIMPLE   
           table: NULL  
             type: NULL  
possible_keys: NULL  
            key: NULL  
        key_len: NULL  
               ref: NULL  
             rows: NULL  
            Extra: SELECT tables optimized away

对user表的单表查询,查询类型为SIMPLE,因为既没有 UNION 也不是子查询。聚合函数 MAX、MIN及COUNT 三者需要的数据都可以通过索引直接定位得到,所以整个实现的 Extra 信息为 SELECT tables optimized away。

再来看一个稍微复杂一点的 Query,一个子查询,如示例代码8-5所示:

代码8-5

sky@localhost : example 11:33:18> EXPLAIN SELECT COUNT(*),MAX(id),MIN(id)   
    -> FROM user\G  
*************************** 1. row ***************************  
             id: 1  
      select_type: SIMPLE  
           table: NULL 
             type: NULL 
possible_keys: NULL 
            key: NULL 
        key_len: NULL 
               ref: NULL 
             rows: NULL 
            Extra: SELECT tables optimized away

通过 id 信息可以得知 MySQL Query Optimizer 给出的执行计划,首先是对 groups 进行全表扫描,第二步才访问 user_group 表,所使用的查询方式是DEPENDENT SUBQUERY,对所需数据的访问方式是索引扫描,由于过滤条件是一个整数,所以索引扫描的类型为 ref,过滤条件是 const。可以使用的索引有两个,一个是基于 user_id,另一个则是基于 group_id 的。为什么基于 group_id 的索引 user_group_gid_ind 也被列为可选索引了呢?是因为与子查询的外层查询所关联的条件是基于 group_id 的。当然,最后 MySQL Query Optimizer 还是选择了使用基于 user_id 的索引 user_group_uid_ind。

由于篇幅关系,这里就不再继续举例了,大家可以通过 Explain 功能分析应用环境中的各种 Query,了解它们在MySQL 中到底是怎么运行的。


关于MySQL 性能分析及 explain 的使用mysql性能分析语句的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于1、查看操作系统 2、查看命令帮助的几种方式 3、pwd 的使用 4、mkdir 的使用、3.Mysql-Explain、dialog 的使用 包括 FLAG_DIM_BEHIND 和 dimAmount 的使用、Explain 的使用--《MySQL性能调优与架构设计》节选等相关知识的信息别忘了在本站进行查找喔。

本文标签: