Maison > Article > base de données > MySQL索引优化分析,SQL优化,慢查询分析
1 配置环境的说明 MySQL的版本信息: 系统版本信息: 2 索引的分析 2.1数据准备 2.1.1数据库建表SQL 表的说明: id是自增主键,name是唯一索引,age 是非唯一索引,desc无索引 CREATE TABLE `index_test` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT C
CREATE TABLE `index_test` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID', `name` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '名字', `age` int(11) NOT NULL COMMENT '年龄', `desc` varchar(128) CHARACTER SET utf8 NOT NULL DEFAULT '' COMMENT '描述', `status` tinyint(4) NOT NULL COMMENT '状态', PRIMARY KEY (`id`), UNIQUE KEY `uniq_name` (`name`), KEY `idx_age` (`age`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
在MySQL中可以在sql前面加上explain语句,来显示该条SQL的执行计划,输出内容如下:
select_type表示查询语句的类型,取值主要有以下几种:
simple:表示是简单的单表查询
primary:表示子查询的外表
derived:派生表的查询
subquery: 子查询的内部第一个SQL
union:表示union操作被连接的表
union result:表示连接操作之后的结果表
depend union 表示子查询中union语句
depend subquery 表示子查询中生成的结果
当前SQL查询涉及到的表的表名,注意 这里有时候是中间结果表的表名,MySQL会按照自己的规则生成
ref非唯一索引查询
range 使用唯一索引返回扫描
index 扫描整个索引文件,例如覆盖索引的查询,效率只是比全表查询略快,因为索引文件一般比数据文件小,所以一次读入内存的索引数据更多,这样磁盘IO 就会更少
All表示全表扫描,是效率最低的一种查询
distinct 查找唯一值,一旦找到就不在继续查找了(暂时没有想好例子)
record 没有找到理想的索引
use file sort 使用外排来排序 效率比较低
use index 使用覆盖索引返回数据,没有扫描表
use tempoary 使用临时表来组合返回数据 效率较低
use where 使用where条件过滤返回的数据,在MySQL的存储引擎层没有过滤完数据,只能在MySQL服务层去过滤数据
SELECT @@profiling 返回的结果如果是0 表示当前的session的profiling功能是关闭的 set profiling=1 打开当前session的profiling功能
SHOW PROFILE [type [, type] ... ] [FOR QUERY n] [LIMIT row_count [OFFSET offset]] type: ALL | BLOCK IO | CONTEXT SWITCHES | CPU | IPC | MEMORY | PAGE FAULTS | SOURCE | SWAPS使用示例:
结果说明:
在使用profiling查看sql的详细执行计划的时候,主要关注的是前两列即:status和duration
status 表示sql的执行状态和 show full process list 查看到的状态一致
duration 表示每个状态执行的时间 可以看到sql的主要执行时间消耗在哪里
其次需要关注的是cup,io,swap的详细信息
cup表示 cpu的消耗时间
swap表示机器的swap情况
io表示io的消耗情况
在使用or作为筛选条件的时候,or的前后筛选条件都必须添加索引 这样才能使用索引 否则 整条sql都无法使用索引