在公司后台某模块功能记录日志中有一个搜索功能,通过前段时间的产品使用时间区间进行搜索反馈有些卡顿,我发现这个搜索功能比较慢,要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. 【驱动】——错误: 初始值设定项里有未知的字段‘ioctl’

    这个错误网上搜索发现3.0.0.15版本内核 file_operation结构体已经删除了ioctl函数,取代的是: long (*unlocked_ioctl) (struct file *, un ...

  2. linux下安装redis并配置

    redis官网上给出了安装步骤,这里做一下总结. 1.Download, extract and compile Redis with: wget http://download.redis.io/r ...

  3. python 核心编程 01

    特殊变量 python用下划线作为变量的前缀和后缀指定特殊变量._XXX : 不用 'from module import *' 导入, 可以认为是模块中的私有变量__XXX__ : 系统定义的名字_ ...

  4. php 扫描 下载 apk

    $file = 'C:\WebSiteDirectory\CarparkWeixinBackend\Dplus.apk'; if (file_exists($file)) { header('Cont ...

  5. 升级ndk后Android studio的build错误

    上周末升级了ndk,应该是最新版的v17.0版本了,当时也没测试,屁颠屁颠的就回家撸猫了... 今天一跑代码在build时报错: ABIs [armeabi] are not supported fo ...

  6. -26628 loadrunner

    在Vuser脚本编译执行无误情况下,在controller中进行并发操作,并发数设为10,只通过5个,失败的报错信息是:   Action.c(15): Error -26628: HTTP Stat ...

  7. OSPF中 hello报文的 内容

    邻居关系通过hello报文来建立.Hello报文中包含如下一些内容: 1.始发路由器的router-id 2.始发路由器接口的area-id 3.始发路由器接口的地址掩码 4.始发路由器接口的auth ...

  8. CentOS执行ping命令报错 name or service not know

    在虚拟机上安装的CentOS,但是当执行ping命令的时候,提示name or service not known 解决方法如下: 1. 添加DNS服务器 vi /etc/resolv.conf 1 ...

  9. git远程库与本地联系报错fatal: Not a git repository (or any of the parent directories): .git

    在github上新建了一个仓库,然后相与本地的仓库联系起来 $ git remote add origin https://github.com/liona329/learngit.git fatal ...

  10. linux之sshfs

    1.挂载 sshfs -p shiyu@ml.cs.tsinghua.edu.cn:/mfs/shiyu/ ~/mfs 2.卸载 fusermount -u ~/mfs