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 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 ;

2.1.2 表中测试数据

2.2 索引分析

2.2.1 使用explain查看sql的执行计划

在MySQL中可以在sql前面加上explain语句,来显示该条SQL的执行计划,输出内容如下:

2.2.2 explain详解

2.2.2.1 select_type

select_type表示查询语句的类型,取值主要有以下几种:

simple:表示是简单的单表查询

primary:表示子查询的外表

derived:派生表的查询

subquery: 子查询的内部第一个SQL

union:表示union操作被连接的表

union result:表示连接操作之后的结果表

depend union 表示子查询中union语句

depend subquery 表示子查询中生成的结果

2.2.2.2 table

当前SQL查询涉及到的表的表名,注意 这里有时候是中间结果表的表名,MySQL会按照自己的规则生成

2.2.2.3 type

type的取值在很大的程度上反应了SQL的执行性能,

按照性能由高到底,type的取值依次为:NULL,system,const,eq_reg,ref,range,index,ALL

NULL 不用查表,速度最快

                                

                              system当表中只有一条数据的时候 type为system

                              const常数查询 一般是根据唯一键或者主键等值查询

                                

eq_reg 表连接的时候 在b表查询出来的结果在a表这中按照唯一索引值查询一行

                               

                             ref非唯一索引查询

                              

                            range 使用唯一索引返回扫描

                              

                          index 扫描整个索引文件,例如覆盖索引的查询,效率只是比全表查询略快,因为索引文件一般比数据文件小,所以一次读入内存的索引数据更多,这样磁盘IO                             就会更少

                           

                         All表示全表扫描,是效率最低的一种查询

2.2.2.4 possible key

表示可能使用的索引,显示的顺序与表连接的顺序无关

2.2.2.5 key

表示MySQL执行本条sql选的索引的名字,可以通过force idex 和 ignore index 来强制改变sql执行所需要的索引

2.2.2.6 key_len

表示该条索引的占用的自己树,是根据索引字段的类型计算出来的,

例如  int(11)  索引长度是4

varchar(128)并且编码是U8  索引长度的计算方法为 : 128*3+2

2.2.2.7 ref

表示使用哪个列从表中选择行,取值有科恩个是const

2.2.2.8 rows

表示执行该条SQL必须扫描的行数

2.2.2.8 extra

包含了MySQL生成执行计划的详细信息:

distinct 查找唯一值,一旦找到就不在继续查找了(暂时没有想好例子)

record 没有找到理想的索引

use file sort 使用外排来排序  效率比较低

use index 使用覆盖索引返回数据,没有扫描表

use tempoary 使用临时表来组合返回数据 效率较低

use where 使用where条件过滤返回的数据,在MySQL的存储引擎层没有过滤完数据,只能在MySQL服务层去过滤数据

2.3 profiling详解

2.3.1 开启profiling

因为profiling是比较消耗资源的,所以一般的MySQL默认都关闭了profiling功能,并且profiling只是针对当前session有效,目前不支持全局的profiling,可以通过如下的命令查看并开发profiling功能:

SELECT @@profiling  返回的结果如果是0 表示当前的session的profiling功能是关闭的

set profiling=1 打开当前session的profiling功能

2.3.2 profiling的使用

2.3.2.1 查询当前session的profiling的概要信息

可以使用 show profiles命令获取当前session所执行的sql的概要信息

2.3.2.2 profiling详解

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的消耗情况

3 无效索引

在很多时候MySQL的表建立了索引,并且在查询条件中也使用了索引进行筛选,但是并不一定会使用到索引,例如下面的几种情况

3.1筛选条件包含了隐式转换

下面的例子中,name字段添加了唯一索引,但是name字段的类型是varchar类型的,而筛选添加时int类型,发生了隐式转换,所以走全表扫描。这里比较隐晦。在上周有一个项目分析酒店订单的时候,本来hive中的酒店订单包含了酒店项目的所有订单,订单id是varchar类型的,而我们需要统计QTA中参加某一个活动的订单,需要查询QTA的订单详情库,(QTA订单详情是hive中订单的子集)里面的订单ID是long类型的,最开始查询的时候就直接在一个表查询完后再另外一个表查询,结果看到一条简单的sql执行起来巨慢。最后分析原因就定位到了这个上面。

3.2 不支持函数式索引

age字段上面添加了非唯一索引,但是使用了绝对值函数,所以age字段上面的索引就无法使用了。这个在处理日期的时候经常遇到这样的坑

3.3 索引扫描的代价大于直接全表扫描

如果只有索引过滤的数据比较少,那么会直接走全表扫描,因为使用索引的时候会先扫描一遍索引,然后根据扫描到的索引回表找到所需要的数据,这样扫描的效率其实更低,所以直接走全表扫描

3.4 使用“%”前缀匹配的时候

name字段添加了唯一索引 但是使用‘%’作为前缀匹配条件,所以不使用索引,直接走全表扫描

3.5 复合索引非左前缀匹配

在使用复合索引的时候 如果不是使用的左前缀筛选条件 则不会使用索引,还是会全表扫描

3.5 or筛选添加前后都有索引的时候才会走索引

在使用or作为筛选条件的时候,or的前后筛选条件都必须添加索引 这样才能使用索引 否则 整条sql都无法使用索引

时间: 2024-10-07 14:04:31

MySQL索引优化分析和SQL优化的相关文章

MySQL索引使用方法和性能优化

关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车.对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能会产生几十万甚至几百万的数据,没有索引查询会变的非常缓慢.还是以WordPress来说,其多个数据表都会对经常被查询的字段添加索引,比如wp_comments表中针对5个字段设计了BTREE索引. 一个简单的对比测试 以我去年测试的数据作为一个简单示例,20多条数据源随机生成200万条

MySQL 索引性能分析概要

上一篇文章 MySQL 索引设计概要 介绍了影响索引设计的几大因素,包括过滤因子.索引片的宽窄与大小以及匹配列和过滤列.在文章的后半部分介绍了 数据库索引设计与优化 一书中,理想的三星索引的设计流程和套路,到目前为止虽然我们掌握了单表索引的设计方法,但是却没有分析预估索引耗时的能力. 在本文中,我们将介绍书中提到的两种分析索引性能的方法:基本问题法(BQ)和快速估算上限法(QUBE),这两种方法能够帮助我们快速分析.估算索引的性能,及时发现问题. 基本问题法 当我们需要考虑对现有的 SELECT

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

一.百万级数据库优化方案 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库. 备注.描述.评论之类的可以设置为 NULL,其他的,最好不要使用NULL. 不要以为 NULL 不需要空间,

索引、视图、SQL优化以及数据库存储过程

一.索引 索引是查询优化最有效和最常用的技术 索引是一个单独的.物理的数据库结构,它是指向表中某一列或若干列上的指针列表. mysql中,一个表的物理存储由两部分组成,一部分用于存放表的数据,另一部分存放索引,当进行数据搜索时,mysql会首先搜索索引,从中找到所需数据的起始位置的指针,再直接通过指针查找目标数据. 1.创建索引: CREATE INDEX 索引名 on 表名(要添加索引的列名) 可以给一个表中的多个列添加索引 通过在查询sql语句前加一句Explain可以分析索引效率, 有这样

mysql优化方案之sql优化

优化目标 1.减少 IO 次数 IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当然,也是收效最明显的优化手段. 2.降低 CPU 计算 除了 IO 瓶颈之外,SQL优化中需要考虑的就是 CPU 运算量的优化了.order by, group by,distinct … 都是消耗 CPU 的大户(这些操作基本上都是 CPU 处理内存中的数据比较运算).当我们的 IO 优化

MySQL索引及Explain及常见优化

MySQL索引设计的原则 1. 搜索的索引列,不一定是所要选择的列.换句话说,最适合索引的列是出现在WHERE 子句中的列,或连接子句中指定的列,而不是出现在SELECT 关键字后的选择列表中的列. 2. 使用惟一索引.考虑某列中值的分布.对于惟一值的列,索引的效果最好,而具有多个重复值的列,其索引效果最差.例如,存放年龄的列具有不同值,很容易区分各行.而用来记录性别的列,只含有" M"和"F",则对此列进行索引没有多大用处(不管搜索哪个值,都会得出大约一半的行)

MySQL索引题目分析

1.之前看视频呢的时候,里面提到一道索引题目:假设某个表有一个联合索引(c1,c2,c3,c4)-只能使用该联合索引的c1,c2,c3部分 a.where c1=x and c2=x and c4>x and c3=x b.where c1=x and c2=x and c4=x order by c3 c.where c1=x and c4=x group by c3,c2 d.where c1=? and c5=? order by c2,c3 e.where c1=? and c2=? a

深入浅出Hive企业级架构优化、Hive Sql优化、压缩和分布式缓存(企业Hadoop应用核心产品)

一.本课程是怎么样的一门课程(全面介绍)    1.1.课程的背景       作为企业Hadoop应用的核心产品,Hive承载着FaceBook.淘宝等大佬 95%以上的离线统计,很多企业里的离线统计甚至全由Hive完成,如我所在的电商.       Hive在企业云计算平台发挥的作用和影响愈来愈大,如何优化提速已经显得至关重要.       Hive作业的规模决定着优化层级,一个Hive作业的优化和一万的Hive作业的优化截然不同.       拥有1万多个Hive作业的大电商如何进行Hiv

MySQL索引原理及SQL优化

原文:MySQL索引原理及SQL优化 目录 索引(Index) 索引的原理 b+树 MySQL如何使用索引 如何优化 索引虽好,不可滥用 如何验证索引使用情况? SQL优化 explain查询执行计划 id select_type table type possible_keys key key_len ref rows Extra 优化数据库结构 优化数据大小 优化数据类型 索引(Index) MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.索引的建立对