本文共 3783 字,大约阅读时间需要 12 分钟。
explain plan for select * from THIRD_ORDER_INFO t left join MER_INFO m on t.MER_NO = m.MER_NO where m.PROVICE_CODE = '11'; SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));
explain 计划,缩进最多的先执行,同样缩进,从上往下执行;
operation 表示当前操作内容,rows 表示 oracle 预估当前操作返回的结果集,
// 表的访问方式 全表扫描:Full Table Scans 通过 ROWID 访问表:table access by ROWID 索引范围扫描:INDEX RANGE SCAN 索引唯一性扫描:INDEX UNIQUE SCAN 索引全扫描:INDEX FULL SCAN 索引快速扫描:index fast full scan 索引跳跃式扫描:INDEX SKIP SCAN
Access,表示如何定位到需要的数据,然后取出该结果集,这个定位的条件,会决定访问是走表,还是索引;Filter,表示过滤条件,通过 filter 过滤掉不需要的数据;
更复杂的查询,会有统计信息 Statistics 的说明;
Statistics 中的 recursive calls,表示执行一条 sql 语句时,产生对其他额外 sql 语句的调用,这部分额外 sql 语句,称为 recursive calls,如 insert 操作,如果没有空间保存,就需要额外 sql 语句来释放空间,分配空间;
Statistics 中的 db block gets,表示从高速缓冲区 buffer cache 中,读取的 block 数;
Statistics 中的 consistent gets,表示从 buffer cache 中,读取 undo 数据的 block 数,产生原因是查询时,其他会话在对数据块操作,导致查询时有了修改,所以需要读取修改之前的数据,保证一致性读;
Statistics 中的 physical reads,表示从磁盘读取的 block 数,是由于缓存中不存在要查询的数据,才需要磁盘查询,该值过高,就需要进行优化,增大数据缓冲区大小等措施;
数据缓冲区的使用命中率 = 1 - ( physical reads / (db block gets + consistent gets))
// 数据库服务器通过 SQL*Net 向查询客户端发送的查询结果字节数 bytes sent via SQL*Net to client // 通过 SQL*Net 接受的来自客户端的数据字节数 bytes received via SQL*Net from client // 服务器和客户端,来回往返通信的 Oracle Net messages 条数 SQL*Net roundtrips to/from client // 在内存执行的排序量 sorts (memory) // 在磁盘上执行的排序量 sorts (disk) // 处理的数据的行数 rows processed
explain sql 语句,explain extended sql 语句,explain partitions sql 语句,表示多显示一个分区信息,对分区表,有效;
示例 explain select name from actor group by name,
id 列,代表一个查询,id 值越大,执行优先级越高,如果 id 值相同,则从上往下执行,id 为 null,最后执行;
select_type,代表查询类型,有 simple,表示简单查询,primary,表示复杂查询中最外层的 select,subquery,表示包含在 select 中的子查询,不在 from 子句中,derived,代表包含在 from 子句中的子查询;
table,代表要查询的表,partitions,代表使用的分区,非分区表,为 null;
type,代表 mysql 使用何种方式来完成查询,从效率最优到最差,分别为 null > system > const > eq_ref > ref > range > index > ALL,通常保证查询达到 range 级别,最好达到 ref,否则就需要优化;
null:表示不需要索引或表查询,如 select 1+2 const, system:表示查询条件被优化成一个常量,如 primary key 或 unique key 的列与常数比较时,只需索引比较, 读取 1 次,速度很快,如 explain select * from actor where id = '1';; eq_ref:表示 primary key 或 unique key 索引的列被连接使用 ,最多只会返回一条符合条件的记录, ref:查询时,使用普通索引或者唯一性索引的部分前缀,索引和某个值相比较,可能会找到多个符合条件的行。 如 explain select * from actor where name = 'a'; name 上有普通索引 range:出现在 in(), between ,> ,<, >= 等操作中,使用索引来检索给定范围的行。 如 explain select * from actor where name in ('a'); index:扫描全表索引,这通常比ALL快一些。(index是从索引中读取的,而all是从硬盘中读取) 如 explain select name from actor; name 字段有索引,且不需要回表查询,所以直接索引查询,可以返回 ALL:即全表扫描,意味着 mysql需要对表,从头到尾查找所有需要的行,通常情况下需要增加索引来进行优化 如 explain select * from actor;
possible_keys,代表可能使用的索引列,key,代表实际执行时,mysql 使用的索引,如果没有使用索引,值为 null,使用 force index 或者 ignore index,可以强制 mysql 使用,或忽视 possible_keys 中的索引;
key_len,代表索引中,使用的字节数,char(n) 值为 n,varchar(n) 值为 2 * 字符串长度,如果 utf-8 编码,值为 3n + 2,int 值为 4,timestamp 值为 4,如果允许为 null,需要 1 字节记录是否为 null,且索引最大长度是 768 字节,超过会截断;
ref,代表 key 记录的索引,使用的列或常量,有 const(常量),字段名,下图中,首先对表 a,使用 const 索引查找,然后根据 a.id 对表 f 进行索引查找;
rows,代表 mysql 预估需要读取并检查的行数,注意这个不是结果集里的行数;
Extra,代表查询的额外信息,如使用索引情况,是否用到排序,临时表等信息;
null :表示使用到索引,但只通过索引,无法获取查询结果,需要回表 using index :表示只查询索引,可以得到查询结果,且 where 条件只用到索引前导列就可定位到结果 using where : 表示没有用到索引 using where using index :表示只查询索引即可,但 where 条件用到索引的非前导列,或者 like 查询 using index condition :表示使用到索引,但通过索引无法获取查询结果的所有列,需要回表,且与 null 不同的是,使用 索引的范围查找,非等值查找 using temporary :查询结果需要创建一张临时表,此时往往需要优化,通过创建索引 using filesort :涉及排序,但排序字段没有索引,需要先查出排序字段+主键,然后按排序字段排序,再根据主键回表, 也往往需要优化,创建索引