1.冗余和重复索引

  mysql允许在相同列上创建多个索引,无论是有意还是无意,mysql需要单独维护重复的索引,并且优化器在优化查询的时候也需要逐个地进行考虑,这会影响性能。重复索引是指的在相同的列上按照相同的顺序创建的相同类型的索引,应该避免这样创建重复所以,发现以后也应该立即删除。但,在相同的列上创建不同类型的索引来满足不同的查询需求是可以的。

  冗余索引和重复索引有一些不同,如果创建了索引(a,b),再创建索引(a)就是冗余索引,因为这只是前面一个索引的前缀索引,因此(a,b)也可以当作(a)来使用,但是(b,a)就不是冗余索引,索引(b)也不是,因为b不是索引(a,b)的最左前缀列,另外,其他不同类型的索引在相同列上创建(如哈希索引和全文索引)不会是btree索引的冗余索引。

  另外:对于二级索引(a,id),id是主键,对于innodb来说,主键列已经包含在二级索引中了,所以这个也是冗余索引。大多数情况下都不需要冗余索引,应该尽量扩展已有的索引而不是创建新索引,但也有时候处于性能方面的考虑需要冗余索引,因为扩展已有的索引会导致其变得太大,从而影响其他使用该索引的查询性能。如:如果在整数列上有一个索引,现在需要额外增加一个很长的varchar列来扩展该索引,那么性可能会急剧下降,特别是有查询把这个索引当作覆盖索引,或者这是myisam表并且有很多范围查询的时候(由于myisam的前缀压缩)。

如:表userinfo,myisam引擎,有100W行记录,每个state_id值大概2W行,在state_id列有一个索引对下面的查询有用:如:select count(*) from userinfo where state_id=5;测试每秒115次QPS

对于下面的查询这个state_id列的索引就不太顶用了,每秒QPS是10次

select state_id,city,address from userinfo where state_id=5;

  如果把state_id索引扩展为(state_id,city,address),那么第二个查询的性能更快了,但是第一个查询却变慢了,如果要两个查询都快,那么就必须要把state_id列索引进行冗余了。但如果是innodb表,不冗余state_id列索引对第一个查询的影响并不明显,因为innodb没有使用索引压缩,myisam和innmodb表使用不同的索引策略的select查询的qps测试结果(以下测试数据仅供参考):

只有state_id列索引    只有state_id_2索引    同时有两个索引

myisam,第一个查询    114.96                25.40                112.19

myisam,第二个查询    9.97                  16.34                16.37

innodb,第一个查询    108.55                100.33               107.97

innodb,第二个查询    12.12                 28.04                28.06

从上图中可以看出,两个索引都有的时候,缺点是成本更高,下面是在不同的索引策略时插入innodb和myisam表100W行数据的速度(以下测试数据仅供参考):

      只有state_id列索引    同时有两个索引

innodb,对有两个索引都有足够的内容的时候       80秒                136秒

myisam,只有一个索引有足够的内容的时候        72秒                470秒

  可以看到,不论什么引擎,索引越多,插入速度越慢,特别是新增索引后导致达到了内存瓶颈的时候。解决冗余索引和重复索引的方法很简单,删除这些索引就可以了,但首先要做的是找出这样的索引,可以通过一些复杂的访问information_schema表的查询来找,不过还有两个更简单的方法,使用:shlomi noach的common_schema中的一些视图来定位,也可以使用percona toolkit中的pt-dupulicate-key-checker工具,该工具通过分析表结构来找出冗余和重复的索引,对于大型服务器来说,使用外部的工具更合适,如果服务器上有大量的数据或者大量的表,查询information_schema表可能会导致性能问题。建议使用pt-dupulicate-key-checker工具。

在删除索引的时候要非常小心:

  如果在innodb引擎表上有where a=5 order by id 这样的查询,那么索引(a)就会很有用,索引(a,b)实际上是(a,b,id)索引,这个索引对于where a=5 order by id 这样的查询就无法使用索引做排序,而只能使用文件排序了。所以,建议使用percona工具箱中的pt-upgrade工具来仔细检查计划中的索引变更。

2. 未使用的索引

除了冗余索引和重复索引,可能还会有一些服务器永远不使用的索引,这样的索引完全是累赘,建议考虑删除,有两个工具可以帮助定位未使用的索引:

  A:在percona server或者mariadb中先打开userstat=ON服务器变量,默认是关闭的,然后让服务器运行一段时间,再通过查询information_schema.index_statistics就能查到每个索引的使用频率。

  B:使用percona toolkit中的pt-index-usage工具,该工具可以读取查询日志,并对日志中的每个查询进行explain操作,然后打印出关羽索引和查询的报告,这个工具不仅可以找出哪些索引是未使用的,还可以了解查询的执行计划,如:在某些情况下有些类似的查询的执行方式不一样,这可以帮助定位到那些偶尔服务器质量差的查询,该工具也可以将结果写入到mysql的表中,方便查询结果。

mysql重复索引、冗余索引、未使用索引的定义和查找的更多相关文章

  1. sql查询未走索引问题分析之查询数据量过大

    前因: 客户咨询,有一个业务sql(代表经常被执行且重要),全表扫描在系统占用资源很高(通过ash报告查询得到信息) 思路: 1.找到sql_text,sql_id 2.查看执行计划 3.查询sql涉 ...

  2. MySQL索引的维护与优化——查找重复及冗余索引

    方法一:通过MySQL的information_schema数据库 查找重复与冗余索引 SELECT a.table_schema AS '数据库', a.table_name AS '表名', a. ...

  3. mysql慢查询Slow Query Log和未使用索引(Not Using Indexes)查询配置和使用

    mysql的“慢查询”指的是超过了允许的最大查询时间(long_query_time)的sql语句,而“未使用索引”查询顾名思义就是查询语句没有使用到索引的sql语句. 慢查询配置和使用 在msyql ...

  4. 点评阿里JAVA手册之MySQL数据库 (建表规约、索引规约、SQL语句、ORM映射)

    下载原版阿里JAVA开发手册  [阿里巴巴Java开发手册v1.2.0] 本文主要是对照阿里开发手册,注释自己在工作中运用情况. 本文内容:MySQL数据库 (建表规约.索引规约.SQL语句.ORM映 ...

  5. mysql(函数,存储过程,事务,索引)

    函数 MySQL中提供了许多内置函数: 内置函数 一.数学函数 ROUND(x,y) 返回参数x的四舍五入的有y位小数的值 RAND() 返回0到1内的随机值,可以通过提供一个参数(种子)使RAND( ...

  6. MySql视图、存储过程、函数、索引

    一.视图 视图是查询命令结果构成的一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集合,并可以当作表来查询使用. 1创建视图 - ...

  7. MySQL学习(一)日志与索引 --- 2019年1月

    1.MySQL的架构 1).连接器 先根据Ip和端口号,用户名和密码,连接MySQL数据库,连接后如果没有下一步动作,连接就处于空闲状态,此时有一个连接超时时间的设置 wait_timeout默认8小 ...

  8. mysql优化:慢查询分析、索引配置优化

    一.优化概述二.查询与索引优化分析a.性能瓶颈定位show命令慢查询日志explain分析查询profiling分析查询b.索引及查询优化三.配置优化 max_connections back_log ...

  9. mysql 拾遗提高(函数、事务、索引)

    目录 1.tips 2.事务(transaction) 3.索引(index) 4.数据库的导出和备份 5.函数 6.防SQL注入 7.使用Explain分析SQL语句 8.视图(view) 1.ti ...

随机推荐

  1. java实现MD5加密

    mport java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Creat ...

  2. php完全销毁session

    <?php session_start(); session_unset(); session_destroy(); ?> session_unset()释放当前在内存中已经创建的所有$_ ...

  3. requirejs解决异步模块加载方案

    他首先会遍历enableRegistry取出其中定义的模块,并且将没有加载成功的模块标识注入noLoads数组,如果过期了这里就会报错 如果上述没问题还会做循环依赖的判断,主要逻辑在breakCycl ...

  4. easyui datagrid 单选框 效果

    columns: [[{            field: 'oid',            title: '选择',            width: 20,            forma ...

  5. Code Snippet

    Code Snippet: http://msdn.microsoft.com/en-us/library/z41h7fat.aspx CodePlex.Snippets 4.0 - Visual S ...

  6. NEC学习 ---- 模块 -文本圆角背景导航

    下图是效果图: 然后, 左右两边的圆角图片和背景图片如下 (因为截图工具的原因, 可能图片不是很清晰. 这个图片有4个部分, 分别是中间的背景图, 左右圆角以及栏目分隔白线) 思路: 利用inline ...

  7. lr并发量和迭代的区别

    1.并发量 并发量也就是同时运行的量.比如100个用户同时登录,那么并发量就是100.当然这100个用户可以进行参数化,也可以采用设置虚拟用户数(vuser). 2.迭代 迭代就是单个用户运行的次数. ...

  8. Android WebApp开发使用Genymotion连接Fiddler2/Charles代理调试

    1.       目的 在模拟器的浏览器或app hybrid开发中遇到chrome调试代码为线上代码或者混淆代码时,可以利用fiddler/charles为genymotion配置代理, 可以方便的 ...

  9. Java-马士兵设计模式学习笔记-代理模式-聚合与继承方式比较

    一.概述 1.目标:要在Tank的move()方法做时间代理及日志代理(可以设想以后还要增加很多代理处理),且代理间的顺序可活更换 2.思路: (1)聚合:代理类聚合了被代理类,且代理类及被代理类都实 ...

  10. JQuery-筛选

    /* 六丶筛选 */ // console.log( $("div:first") ); // div#id_1 所有div中的第一个 // console.log( $(&quo ...