使用explain来分析SQL语句实现优化SQL语句

用法:explain sql

作用:用于分析sql语句

mysql> explain select * from quser_1 where loginemail = "[email protected]";
+----+-------------+---------+------+-----------------+-----------------+---------+-------+------+-----------------------+
| id | select_type | table   | type | possible_keys   | key             | key_len | ref   | rows | Extra                 |
+----+-------------+---------+------+-----------------+-----------------+---------+-------+------+-----------------------+
|  1 | SIMPLE      | quser_1 | ref  | loginemailindex | loginemailindex | 302     | const |    1 | Using index condition |
+----+-------------+---------+------+-----------------+-----------------+---------+-------+------+-----------------------+
1 row in set

mysql>

  

0: id表示执 explain 的一个编号(没有实际意义)

1:table 查询的表名

2:select_type查询类型,是单表查询、联合查询还是子查询,可能会出现以下值:

查询类型 说明
SIMPLE 简单的 select 查询,不使用 union 以及子查询
PRIMARY 最外层的 select 查询(使用到主键作为查询条件)
UNION UNION UNION 中的第二个或者随后的 select 查询,不依赖于外部查询的结果集
DEPENDENT UNION UNION 中的第二个或者随后的 select 查询,依赖于外部查询的结果集
SUBQUERY 子查询中的第一个 select 查询,不依赖于外部查询的结果集
DEPENDENT SUBQUERY 子查询中的第一个 select 查询,依赖于外部 查询的结果集
DERIVED 用于 from 子句里有子查询的情况。 MySQL 会 递归执行这些子查询, 把结果放在临时表里
UNCACHEABLE SUBQUERY 结果集不能被缓存的子查询,必须重新为外 层查询的每一行进行评估
UNCACHEABLE UNION UNION UNION中的第二个或随后的 select 查询,属 于不可缓存的子查询

例如使用如下表结构:

CREATE TABLE `quser_1` (
  `quserid` int(10) unsigned NOT NULL DEFAULT ‘0‘,
  `username` varchar(64) NOT NULL DEFAULT ‘‘,
  `id` int(10) unsigned NOT NULL DEFAULT ‘0‘,
  `ver` int(10) unsigned NOT NULL DEFAULT ‘0‘,
  `password` varchar(40) NOT NULL DEFAULT ‘‘,
  `randomkey` varchar(30) NOT NULL DEFAULT ‘‘,
  `sealtime` varchar(30) NOT NULL DEFAULT ‘‘,
  `status` tinyint(1) NOT NULL DEFAULT ‘0‘,
  `src` varchar(50) NOT NULL DEFAULT ‘‘,
  `ip` varchar(11) NOT NULL DEFAULT ‘0‘,
  `regtime` datetime NOT NULL DEFAULT ‘0000-00-00 00:00:00‘,
  `tastetime` datetime NOT NULL DEFAULT ‘0000-00-00 00:00:00‘,
  `lastmodifytime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `loginemail` varchar(100) NOT NULL DEFAULT ‘‘,
  `loginmethod` tinyint(3) unsigned NOT NULL DEFAULT ‘0‘,
  `va` varchar(1000) NOT NULL DEFAULT ‘‘ COMMENT ‘virtual account info‘,
  PRIMARY KEY (`quserid`) KEY_BLOCK_SIZE=1024,
  UNIQUE KEY `username` (`username`) KEY_BLOCK_SIZE=1024,
  KEY `id` (`id`) KEY_BLOCK_SIZE=1024,
  KEY `loginemailindex` (`loginemail`) KEY_BLOCK_SIZE=2048
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8

  

示例1:使用简单查询

mysql> explain select * from quser_1 where loginemail = "[email protected]";
+----+-------------+---------+------+-----------------+-----------------+---------+-------+------+-----------------------+
| id | select_type | table   | type | possible_keys   | key             | key_len | ref   | rows | Extra                 |
+----+-------------+---------+------+-----------------+-----------------+---------+-------+------+-----------------------+
|  1 | SIMPLE      | quser_1 | ref  | loginemailindex | loginemailindex | 302     | const |    1 | Using index condition |
+----+-------------+---------+------+-----------------+-----------------+---------+-------+------+-----------------------+
1 row in set

mysql>

  

type 说明:

type 说明
system 表仅有一行(=系统表)。这是 const 连接类型的一个特例
const const 用于用常数值比较 PRIMARY KEY 时。当 查询的表仅有一行时,使用 System
eq_ref const 用于用常数值比较 PRIMARY KEY 时。当 查询的表仅有一行时,使用 System
ref 连接不能基于关键字选择单个行,可能查找 到多个符合条件的行。 叫做 ref 是因为索引要 跟某个参考值相比较。这个参考值或者是一 个常数,或者是来自一个表里的多表查询的 结果值
ref_or_null 如同 ref, 但是 MySQL 必须在初次查找的结果 里找出 null 条目,然后进行二次查找
index_merge 说明索引合并优化被使用了
unique_subquery 在某些 IN 查询中使用此种类型,而不是常规的 ref:value IN (SELECT primary_key FROM single_table WHERE some_expr)
index_subquery 在 某 些 IN 查 询 中 使 用 此 种 类 型 , 与 unique_subquery 类似,但是查询的是非唯一 性索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
range 只检索给定范围的行,使用一个索引来选择 行。key 列显示使用了哪个索引。当使用=、 <>、>、>=、<、<=、IS NULL、<=>、BETWEEN 或者 IN 操作符,用常量比较关键字列时,可 以使用 range
index 全表扫描,只是扫描表的时候按照索引次序 进行而不是行。主要优点就是避免了排序, 但是开销仍然非常大
all 最坏的情况,从头到尾全表扫描

示例2:type 为 const

mysql> explain select * from quser_1 where quserid = "3000096101";
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table   | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | quser_1 | const | PRIMARY       | PRIMARY | 4       | const |    1 | NULL  |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
1 row in set

  

示例3: type 为 all (这种是要优化和避免的)

mysql> explain select * from quser_1 where src = "pcw";
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | quser_1 | ALL  | NULL          | NULL | NULL    | NULL | 1274 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
1 row in set

  

示例4: type  为 ref

mysql> explain select * from quser_1 where loginemail = ‘[email protected]‘;
+----+-------------+---------+------+-----------------+-----------------+---------+-------+------+-----------------------+
| id | select_type | table   | type | possible_keys   | key             | key_len | ref   | rows | Extra                 |
+----+-------------+---------+------+-----------------+-----------------+---------+-------+------+-----------------------+
|  1 | SIMPLE      | quser_1 | ref  | loginemailindex | loginemailindex | 302     | const |    1 | Using index condition |
+----+-------------+---------+------+-----------------+-----------------+---------+-------+------+-----------------------+
1 row in set

  

prossible_keys:能在该表中使用哪些索引有助于查询

key:实际使用的索引

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

ref:索引的哪一列被使用了

rows:返回的结果的行数

Extra:其他说明

原文地址:https://www.cnblogs.com/leeyongbard/p/9397840.html

时间: 2024-11-29 07:54:19

使用explain来分析SQL语句实现优化SQL语句的相关文章

SQL数据库数据优化SQL优化总结( 百万级数据库优化方案)

网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉好的话推荐给更多的人,让更多的人看到.纠正以及补充. 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id f

sql语句的优化分析

摘自  http://www.cnblogs.com/knowledgesea/p/3686105.html sql语句性能达不到你的要求,执行效率让你忍无可忍,一般会时下面几种情况. 网速不给力,不稳定. 服务器内存不够,或者SQL 被分配的内存不够. sql语句设计不合理 没有相应的索引,索引不合理 没有有效的索引视图 表数据过大没有有效的分区设计 数据库设计太2,存在大量的数据冗余 索引列上缺少相应的统计信息,或者统计信息过期 .... 那么我们如何给找出来导致性能慢的的原因呢? 首先你要

【转】sql语句的优化分析

开门见山,问题所在 sql语句性能达不到你的要求,执行效率让你忍无可忍,一般会时下面几种情况. 网速不给力,不稳定. 服务器内存不够,或者SQL 被分配的内存不够. sql语句设计不合理 没有相应的索引,索引不合理 没有有效的索引视图 表数据过大没有有效的分区设计 数据库设计太2,存在大量的数据冗余 索引列上缺少相应的统计信息,或者统计信息过期 .... 那么我们如何给找出来导致性能慢的的原因呢? 首先你要知道是否跟sql语句有关,确保不是机器开不开机,服务器硬件配置太差,没网你说p啊 接着你使

简述项目中优化sql语句执行效率的方法,从哪些方面,sql语句性能如何分析?

(1)尽量选择较小的列: (2)将where中用的比较频繁的字段建立索引: (3)select中避免使用*: (4)避免在索引列上使用计算.not in和<>等操作: (5)当只需要一行数据时候使用limit1: (6)保证单表数据不超过200w,实时分割表: 针对查询较慢的语句,可以使用explain来分析该语句具体的执行情况.

[转]一个用户SQL慢查询分析,原因及优化

来源:http://blog.rds.aliyun.com/2014/05/23/%E4%B8%80%E4%B8%AA%E7%94%A8%E6%88%B7sql%E6%85%A2%E6%9F%A5%E8%AF%A2%E5%88%86%E6%9E%90%EF%BC%8C%E5%8E%9F%E5%9B%A0%E5%8F%8A%E4%BC%98%E5%8C%96/ 问题描述 一个用户反映先线一个SQL语句执行时间慢得无法接受.SQL语句看上去很简单(本文描述中修改了表名和字段名):SELECT cou

MySql数据库3【优化2】sql语句的优化

1.SELECT语句优化 1).利用LIMIT 1取得唯一行[控制结果集的行数] 有时,当你要查询一张表是,你知道自己只需要看一行.你可能会去的一条十分独特的记录,或者只是刚好检查了任何存在的记录数,他们都满足了你的WHERE子句.在这种情况下,增加一个LIMIT 1会令你的查询更加有效.这样数据库引擎发现只有1后将停止扫描,而不是去扫描整个表或索引. 2).不要使用BY RAND()命令 这是一个令很多新手程序员会掉进去的陷阱.你可能不知不觉中制造了一个可怕的平静.这个陷阱在你是用BY RAN

如何用 SQL Tuning Advisor (STA) 优化SQL语句

在Oracle10g之前,优化SQL是个比较费力的技术活,不停的分析执行计划,加hint,分析统计信息等等.在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning Advisor :STA),它是新的DBMS_SQLTUNE包.使用STA一定要保证优化器是CBO模式下. 执行DBMS_SQLTUNE包进行sql优化需要有advisor的权限: SQL> create user dave identified by dave; 用户已创建. SQL> gra

mysql优化sql语句

mysql优化sql语句 常见误区 www.2cto.com 误区1: count(1)和count(primary_key) 优于 count(*) 很多人为了统计记录条数,就使用 count(1) 和 count(primary_key) 而不是 count(*) ,他们认为这样性能更好, 其实这是一个误区.对于有些场景,这样做可能性能会更差,应为数据库对 count(*) 计数操作做了一些特别的优化. 误区2: count(column) 和 count(*) 是一样的 这个误区甚至在很多

MySQL数据库学习之SQL语句如何优化?数据库开发

1) 现场抓出慢查询语句 show full processlist; 2) 配置参数: slow_query_log_file = ON 慢查询开启开关 long_query_time =2 记录大于2秒的sql语句 log_queries_not_using_indexes = ON 没有使用索引的sql语句 slow_query_log_file = /application/mysql-5.6.34/data/db01-slow.log 慢log文件 min_examined_row_l