在公司后台某模块功能记录日志中有一个搜索功能,通过前段时间的产品使用时间区间进行搜索反馈有些卡顿,我发现这个搜索功能比较慢,要3秒左右才能出来,就决定对这里做一下优化。

通过分析代码和SQL发现最核心的问题在于一个区间查询耗时太长,耗时2秒多,所以我决定看看这里能不能优化,其中核心SQL为

SELECT  * FROM XXX_log WHERE (`ctime` BETWEEN '2017-09-11 09:34:13'  AND '2017-10-11 09:34:13')
and id > 27851
AND column1 = 'xxx'
AND (column2 = 'null' OR LENGTH(column2) > 91)
ORDER BY id DESC LIMIT 0, 30

这个查询是一个简单查询,没有联表,就是单表的limit分页查询,外加一个时间区间和字段搜索,我通过SQL分析 explain 发现并未走索引,扫描区间也很大,由于该表拥有接近100万的记录,查询的扫描区间接近50万,我感觉这样肯定是效率不高的。

然后查询了一下数据,发现耗时确实在2.6秒左右,我起初的设想是,column2字段查询肯定是没法改了 ,毕竟那涉及到以前的业务,该字段这样搜索查询确实有违常理,但是既然之前的功能已经这样设计了,现在去做调整,反而有可能有问题,那么就只有在 id ctime column1下手了,id它写死了,定了某条记录开始进行查询,我猜测可能之前的数据是测试数据或者是废弃数据,那既然有个标尺,就不去动它,column1是固定的查询值,这样也没法改,这样的固定值在数据行中差异不明显,加索引效果也不大,然后是ctime了,唯一能动文章的也只有它了。

然后我好好分析了一下这个模块要实现的功能逻辑,就是查询这段时间内符合要求的数据,这段时间,很明显是一个月,能不能设定这个查询区间只能查一个星期呢?

我改为一周内的时间区间查询,肯定能降低查询的查询区间啊,然而令人遗憾的是,这个降低查询区间间隔,并没有多大效果,最后无奈,我给ctime添加了一个 normal index btree索引,加了索引后,我本以为一切都会好起来,谁知,explain后效果还是那样!

可能用到的索引keys  主键 ctime  ,然而呢 查询区间还是接近45万,效果并不明显,查询时间也还是2秒多,这可让我犯难了,一时束手无策,思考许久,突然想到这感觉是索引没有真正生效导致的,那么能不能强制告诉mysql使用某个索引了,让他主动是走某个索引,然后我查询了资料 找到了force index(强制要走的那个索引) ,我马上就试了一下

SELECT  * FROM XXX_log force index(ctime) WHERE (`ctime` BETWEEN '2017-09-11 09:34:13'  AND '2017-10-11 09:34:13')
and id > 27851
AND column1 = 'xxx'
AND (column2 = 'null' OR LENGTH(column2) > 91)
ORDER BY id DESC LIMIT 0, 30

果然 explain分析之后 使用了ctime索引

而且查询区间降低到3万多了,这个效果太明显了,耗时降低到0.2秒左右,然后这个功能马上从3秒才能打开降低到0.3秒就能打开了,这个优化效果令我非常满意。

在和运维讨论该表的数据时,运维提供方案说,看到该表数据量庞大 接近100万,并且时间很多是2015年 2016年的,他提出可以转移2015年 2016年的数据,我查看了一下,2015年和2016年的数据合计起来有70多万了,占据了绝大部分,如果转移的话,确实有利于我们查询啊,比对啊,更新啊之类的,因为这是一张日志表,在某个期间具有时效性,毕竟大部分时候今年不会再看去年前年的查询数据了,所以我觉得这种做法也有依据,也合理,恰逢同事请假休息,此事等他回来再做讨论。

本次想到强制使用索引,也是灵光一现,稍微有一些运气在里面的,不然还真不好解决这个问题,算是天公作美吧!遂感慨一首:

苍茫青天显神威,

拦路崔嵬面如灰。

忽而得来灵光现,

开山破土镇边陲!

mysql强制使用索引的更多相关文章

  1. MYSQL强制使用索引和禁止使用索引

    mysql强制索引和禁止某个索引 1.mysql强制使用索引:force index(索引名或者主键PRI) 例如: select * from table force index(PRI) limi ...

  2. mysql 强制走索引

    查询是数据库技术中最常用的操作.查询操作的过程比较简单,首先从客户端发出查询的SQL语句,数据库服务端在接收到由客户端发来的SQL语句后, 执行这条SQL语句,然后将查询到的结果返回给客户端.虽然过程 ...

  3. Mysql: 强制走索引:mysql between 日期索引 索引问题-日期索引使用

    Mysql: mysql between 日期索引 索引问题-日期索引使用 表结构: dep_date dep arr 联合索引: ind_coll_date_route  (dep_date ,de ...

  4. mysql强制索引和禁止某个索引

    1.mysql强制使用索引:force index(索引名或者主键PRI) 例如: select * from table force index(PRI) limit 2;(强制使用主键) sele ...

  5. 强制MySQL查询走索引和强制查询不缓存

    有些情况下,表中创建了索引但是EXPLAIN的查看执行计划的时候发现并没有走索引.是因为优化器认为该语句不使用索引效率更好. 当然也可以强制走索引.类似: SELECT uid,uname FROM ...

  6. [MySQL] 使用force index强制使用索引

    1.在测试一个按照时间的范围查询时,尽管增加了索引,发现使用不到索引,可以使用这个来强制使用索引 测试过程为,创建下面的表,以及创建了联合索引 create table delay_delete_us ...

  7. 数据库 MySQL进阶之索引

    数据库的索引非常重要,基本面试数据库的问题都在索引上,所以这里小编整理出来,一方面为了自己复习,一方面也方便大家. 一,索引前传 在了解数据库索引之前,首先有必要了解一下数据库索引的数据结构基础,那么 ...

  8. MySQL 进阶之索引

    一,索引前传 在了解数据库索引之前,首先有必要了解一下数据库索引的数据结构基础,那么什么样的数据结构可以作为索引呢? B-tree是最常用的用于索引的数据结构.因为它们是时间复杂度低, 查找.删除.插 ...

  9. MySQL笔记(5)---索引与算法

    1.前言 本章记录MySQL中的索引机制,了解索引可以让数据库更快.索引太多会造成性能损耗,索引太少肯定查询效率不高. 2.InnoDB存储引擎所有概述 InnoDB中常见的索引有: B+树索引 全文 ...

随机推荐

  1. 【C】——可变参数

    写代码之前要先介绍一下可变参数的备用知识: C函数要在程序中用到以下这些宏: void va_start( va_list arg_ptr, prev_param ); type va_arg( va ...

  2. Centos warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory

    vi /etc/environment add these lines... LANG=en_US.utf-8 LC_ALL=en_US.utf-8 QQ技术交流群:576269252 ------- ...

  3. Nagios系列1,选择

    Zabbix和Nagios哪个更好 zabbix: 1.分布式监控,适合于构建分布式监控系统,具有node,proxy 2种分布式模式 2.自动化功能,自动发现,自动注册主机,自动添加模板,自动添加分 ...

  4. PHP开发安全问题总结

    php给了开发者极大的灵活性,但是这也为安全问题带来了潜在的隐患,近期需要总结一下以往的问题,在这里借翻译一篇文章同时加上自己开发的一些感触总结一下. 简介 当开发一个互联网服务的时候,必须时刻牢记安 ...

  5. JS不同浏览器图片载入处理

    //不同浏览器图片加载判断 p.loadImgVerify = function(oimg,fn){ //载入发起请求 加入JS单线程队列事件(当状态满足时候执行些事件) if (qp_shared. ...

  6. 【转】【Python】装饰器

    1.闭包 >>> def outer(): ... x = 1 ... def inner(): ... ... return inner >>> foo = ou ...

  7. windows下mysql密码忘了怎么办?【转】

    前两天在windows的command命令行下,用mysqladmin导入过一些站上数据 结果悲催了,mysql.user的内容被改了,root上不了了,权限也变了. 结合了网络上的集中方法,终于成了 ...

  8. ajax 把返回结果作为参数传递

    这个涉及到js的异步执行了,程序本身是同步执行的,到了getJSON这里的时候,这个函数是异步的,而 load_val这个函数是同步的,你需要这样来异步返回这个值 function load_val( ...

  9. C# 使用 Task 替换 ThreadPool ,异步监测所有线程(任务)是否全部执行完毕

    using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; using System.T ...

  10. 《经久不衰的Spring框架:@ResponseBody 中文乱码》(转)

    转载自:http://www.cnblogs.com/shanrengo/p/6429291.html 问题背景 本文并不是介绍@ResponseBody注解,也不是中文乱码问题的大汇总笔记,这些网上 ...