`

Mysql复合索引的坑!!!

阅读更多

 

问题发生!

上周五公司年会,一早运维电话说UIOC,IMS应用的CPU持续飙高,立马启动UIOC。迅速赶到公司情况属实,各种查最终发现DB并发连接数超高,DB负载超高,kafka积压严重,并且持续时间已经有一两个小时了。

 

 

解决方案第一波!

查看IMS应用线程堆栈(ThreadDump)信息发现200个运行线程有167个都在做同一个操作,这个操作是每个用户登录时都要加载自己当天所有的任务并缓存到redis,加载自己所有任务的mysql语句基本如下:

select * from A left outer join B on A.taskid=B.taskid where A.resourceid = '123456' ,其中我们已经有了一个复合索引 (A.modifytime , A.resouceid),复合索引使用方式是从左到右,所以A.resourceid = '123456'根本用不上复合索引,结果是全表扫描。很明显我们sql语句忘记加时间限制,所以当晚改成如下:

select * from A left outer join B on A.taskid=B.taskid where  A.modifytime > 2017-01-09  and A.resourceid = '123456'

 

 

问题第二次发生(+原理解析)!

本以为改成这样,索引一定可以生效运行正常,谁知道过来两天DB又报警,一查还是那条语句的问题。explain执行计划发现会跑偏索引、未命中索引或者只用到复合索引的一半(A.modifytime)。复合索引有两个字段,并且where条件都有,为什么只用到一半。后来了解到mysql复合索引从左到右,遇到范围查询的条件(A.modifytime)时,索引回表后不会再使用复合索引后面的字段。

还有一个问题为什么会跑偏索引或未命中索引?

通过DBA了解到,mysql执行时使用哪个索引是运行时决定的(和oracle不一样),如果SQL引擎认为用索引后回表再进行扫描查询,还不如直接全表扫描时,他可能会不用索引或者用另外一个他认为更合适的索引。

 补:按道理来说用一半索引也可以了,为什么还会报警?主要是因为有些比较大的城市,每天所有用户所有任务量也会很大,命中一半索引,回表后全表扫描DB压力还是很大。特别是早高峰时段压力更为明显!

 

 

解决方案终极波

问题描述到这里,到底怎么解决呢?调整复合索引顺序!

结合业务我们知道,主表中存储此城市所有用户15天的所有任务数据,先用A.resourceid做过滤效果会好很多,再加上时间条件(A.modifytime > 2017-01-09)几乎可以锁定数据到很小一个范围。所以我们调整了复合索引的顺序,即(A.resouceid, A.modifytime),这样那条SQL语句每次都会命中这个索引。上线后第二天高峰时段监控发现,DB的CPU使用率由之前80%降到12%。

 

 参考链接:MYSQL是这么走索引的

http://blog.chinaunix.net/uid-29578485-id-5241735.html

 

 

 

 

 

 

分享到:
评论

相关推荐

    MySQL安装详细教程!!!

    MySQL安装详细教程!!!

    mysql-notes-master.zip

    mysql学习笔记!!!!!!!!!!!!!!!!!!! mysql学习笔记!!!!!!!!!!!!!!!!!!! mysql学习笔记!!!!!!!!!!!!!!!!!!! mysql学习笔记!!!!!!!!!!!!!!!...

    Apache2.2.4+php5.2.5+mysql5.0+discuz!6+ ZendOptimizer-3.3.0a+phpMyAdmin-2.11.3

    这个是安装说明文件,里面要用的安装文件,除了MYSQL 5。0太大,不能上传,其他的都上传了!!安装文件免费共享了,想快速安装成功的兄弟,请下载这个说明文件,我要收3分哦!我也想去下别人的好东西!!呵呵!

    mySQL命令大全!!!

    决对好用的。!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    MySql函数详解!!!

    MySQL数据库提供了很多函数包括: 数学函数:数学函数主要用于处理数字,包括整型、浮点数等。 字符串函数:字符串函数是MySQL中最常用的一类函数,字符串函数主要用于处理表中的字符串。 日期和时间函数:MySQL的...

    MySQL笔记哟!!!

    11. **性能优化**:MySQL性能优化包括查询优化(使用EXPLAIN分析查询计划)、索引优化、内存配置调整、表设计优化和分区策略等。 12. **安全性**:MySQL提供用户权限管理,通过GRANT和REVOKE命令控制用户对数据库的...

    mysql存储与索引技术

    在索引优化方面,最左前缀原则是一个关键概念,这意味着复合索引只能按照索引创建时列的顺序部分使用,例如,INDEX(A, B, C)可以用于 WHERE A = x 或 WHERE A = x AND B = y 的查询,但不能单独用于 WHERE B = y 或 ...

    MySQL小面试题!!!!!

    B+树是MySQL默认的存储引擎InnoDB的索引数据结构,并发修改需要考虑到锁的结构来保证并发修改的正确性和一致性,还需要考虑到锁的粒度来控制开销。 锁的结构有表级锁和行级锁,行级锁的粒度较小,可以避免不必要的...

    MySQL 索引最佳实践

    - **使用复合索引**:通过创建包含多个列的索引,可以同时满足多个查询条件,从而减少索引的数量。 - **定期分析和优化索引**:随着数据的变化,索引的效率也会变化,定期检查和调整索引结构是必要的。 - **利用覆盖...

    MySQL索引 聚集索引

    MySQL索引 聚集索引 如果你想了解MySQL索引查询优化,你首先应该对MySQL数据组织结构、B-Tree索引、聚集索引,次要索引有一定的了解,才能够更好地理解MySQL查询优化行为。这里主要探讨MySQL InnoDB的聚集索引。

    MySQL索引 使用笔记

    - 通常应根据查询条件的频率和数据分布来选择复合索引的列。 6. 索引的选择性: - 选择性越高,索引效率越好。一个列的唯一值越多,选择性越高。 - 对于区分度低的列(如性别或地区),创建索引可能效果不佳。 ...

    Mysql的索引及优化策略

    Mysql的索引及优化策略,个人感觉还不错

    基于Java的网吧管理系统,MySQL数据库,JDBC编程!

    基于Java的网吧管理系统,MySQL数据库,JDBC编程! 基于Java的网吧管理系统,MySQL数据库,JDBC编程! 基于Java的网吧管理系统,MySQL数据库,JDBC编程! 基于Java的网吧管理系统,MySQL数据库,JDBC编程! 基于Java...

    MYSQL创建索引全过程

    代码复制粘贴 改下里面的参数 就可以用 而且参数 也有说明 简单易懂

    MySQL创建索引,查看以及删除

    5. 复合索引(Composite Index):由多个列组成的索引,按列的顺序进行排序。 创建索引的基本语法如下: ```sql CREATE INDEX index_name ON table_name (column_name); ``` 对于复合索引: ```sql CREATE ...

    mysql数据库索引类型

    4. 复合索引( Composite Index):复合索引是指在多个列上创建的索引,用于加速多列查询的速度。 二、MySQL索引的创建与删除 1. 创建索引:可以使用CREATE INDEX语句或在CREATE TABLE语句中指定INDEX关键字来创建...

    mysql中创建各种索引的语句整理.pdf

    Mysql中创建各种索引的语句整理 代码 添加PRIMARY KEY(主键索引) 添加UNIQUE(唯一索引) 添加INDEX(普通索引) 添加FULLTEXT(全文索引) 添加多列索引 ) mysql>ALTER TABLE `...

    mysql的索引

    mysql的索引介绍,mysql的索引介绍mysql的索引介绍mysql的索引介绍mysql的索引介绍mysql的索引介绍mysql的索引介绍

    7月6日 MySQL索引篇

    7月6日 MySQL索引篇7月6日 MySQL索引篇7月6日 MySQL索引篇7月6日 MySQL索引篇7月6日 MySQL索引篇7月6日 MySQL索引篇7月6日 MySQL索引篇7月6日 MySQL索引篇7月6日 MySQL索引篇7月6日 MySQL索引篇7月6日 MySQL索引篇7...

Global site tag (gtag.js) - Google Analytics