工作中接开发主管反馈,有个资讯接口调用时有出现响应较慢,需要优化。

接口返回有时较慢??第一反应是接口的redis缓存过期时有大量请求穿过redis缓存,对mysql访问压力较大造成的。

先看PHP代码,逻辑不复杂,首先根据传入的资讯类型id,从redis获取资讯缓存,没有就读取mysql同时更新redis缓存,缓存有效期3-5分钟。

大概定位在mysql查询这块,然后上阿里云后台发现mysql慢查询记录。

表结构:

资讯分类表
CREATE TABLE `article_cats` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL COMMENT '分类名',
`pid` INT(11) NOT NULL DEFAULT '',
`type` TINYINT(4) NOT NULL DEFAULT '' COMMENT '类型(0文章1视频)',
`img_url` VARCHAR(300) NOT NULL COMMENT '类别ICON',
`sort` INT(11) NOT NULL DEFAULT '' COMMENT '排序(数值越大越靠前)',
PRIMARY KEY (`id`),
UNIQUE INDEX `name` (`name`),
INDEX `sort` (`sort`)
)
COMMENT='文章分类表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=106;
资讯表
CREATE TABLE `article` (
  `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`type` TINYINT(1) UNSIGNED ZEROFILL NULL DEFAULT NULL COMMENT '类型',
`title` VARCHAR(500) NOT NULL COMMENT '标题',
`abstract` VARCHAR(255) NULL DEFAULT '' COMMENT '摘要',
`own` VARCHAR(50) NULL DEFAULT NULL,
`url_md5` VARCHAR(200) NULL DEFAULT NULL COMMENT '文章URL',
`live_status` TINYINT(1) NULL DEFAULT '' COMMENT '显示类型 1 web显示,2 app显示,3 全显示,4 全不显示',
`status` TINYINT(1) NULL DEFAULT '' COMMENT '状态,1正常,-1删除',
`grab_time` DATETIME NULL DEFAULT NULL COMMENT '采集第3方时间',
`img_url` VARCHAR(200) NULL DEFAULT '',
`sort` INT(11) NULL DEFAULT '' COMMENT '文章排序',
`last_own` VARCHAR(20) NULL DEFAULT NULL COMMENT '最后编辑者帐号',
`url` VARCHAR(200) NULL DEFAULT NULL,
`level` TINYINT(4) NULL DEFAULT '' COMMENT '快讯的重要程度:1不重要,2一般,3重要',
`share_num` INT(10) UNSIGNED NOT NULL DEFAULT '' COMMENT '分享数',
`status_level` TINYINT(3) UNSIGNED NOT NULL DEFAULT '' COMMENT '置顶状态',PRIMARY KEY (`id`),
INDEX `title` (`title`(255)),
INDEX
`status` (`status`),
 INDEX `grab_time` (`grab_time`),
INDEX `t_l_s` (`type`, `live_status`, `status`),
INDEX `type` (`type`, `status`, `live_status`),
INDEX `live_status` (`live_status`, `status_level`),
INDEX `Index 11` (`sort`)
) COMMENT='文章表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=537710;
查询sql:
SELECT a.id,a.title,a.img_url,ac.type actype,a.template,a.sort,a.grab_time,a.type as type_id,a.abstract,ac.name as type,ac.img_url as cat_img_url FROM article a left join article_cats ac on a.type = ac.id WHERE ( a.status = 1 ) AND ( ac.pid = 25 ) ORDER BY a.id DESC LIMIT 0,20

/* Affected rows: 0 已找到记录: 20 警告: 0 持续时间 1 query: 0.328 sec. (+ 0.016 sec. network) */

查询结果显示耗时0.3秒,这样的时间间隔在大量请求穿透redis缓存直接访问mysql时肯定会对接口有影响。

用explain执行sql得到如下分析结果:

其中possible_keys列指出MySQL能使用哪个索引在该表中找到行,key列显示MySQL实际决定使用的键(索引)。

可以看到mysql服务端自做判断使用status索引,但status只分两种情况,1和-1,区分度不大,索引用起来效果不佳(当时也不知道谁对status字段建了索引。。。)。

我们可以强制mysql使用区分度大的索引和字段。

这里我们还有type索引:

`type` (`type`, `status`, `live_status`)
加上强制使用的索引sql变成如下
SELECT 

a.id,a.title,a.img_url,ac.type actype,a.template,a.sort,a.grab_time,a.type as type_id,a.abstract,ac.name as type,ac.img_url as cat_img_url

FROM article a force index(type)

 left join article_cats ac 

on a.type = ac.id 

WHERE ( a.status = 1 ) AND ( ac.pid = 25 )

/* Affected rows: 0 已找到记录: 20 警告: 0 持续时间 1 query: 0.015 sec. (+ 0.016 sec. network) */

  查询结果显示耗时0.015秒,查询效率有了很大提升。

再用explain分析

可以发现ac表走全表扫描(资讯类型表一百来号数据),a表使用type索引。

改完后测试环境测试完成么问题,下周来上线。

explain关键字是项目开发过程的一件sql效率提优利器,写sql,特别是联合查询,字表查询之类的时候还是大有裨益。

mysql的join连接查询优化经历的更多相关文章

  1. MySQL的JOIN连接

    MySQL的JOIN join的含义跟英文单词"join"一样,连接连接两张表.分为 内连接:inner join 外连接   (1)左外连接(左边的表不加限制):left joi ...

  2. 一张图看懂Mysql的join连接

    INNER JOIN:当两个表中都匹配时返回行. LEFT JOIN:返回左表中的所有行,即使右表中没有匹配项也是如此. RIGHT JOIN:返回右表中的所有行,即使左表中没有匹配项也是如此. FU ...

  3. mysql各种join连接查询

    最近项目用到了几次sql join查询 来满足银行变态的需求:正好晚上自学时,看到了相关视频,所以记录下相关知识,下次再用时,根据如下图片,便可知道 怎么写sql; 注意点: 在join操作中的 on ...

  4. MySQL之表、列别名及各种JOIN连接详解

    MySQL在SQL中,合理的别名可以让SQL更容易以及可读性更高.别名使用as来表示,可以分为表别名和列别名,别名应该是先定义后使用才对,所以首先要了解sql的执行顺序(1) from(2) on(3 ...

  5. MySQL--7种join连接

    一,定义: 1)LEFT JOIN / LEFT OUTER JOIN:左外连接 左向外连接的结果集包括:LEFT OUTER子句中指定的左表的所有行,而不仅仅是连接列所匹配的行.如果左表的某行在右表 ...

  6. MySQL索引原理以及查询优化

    转载自:https://www.cnblogs.com/bypp/p/7755307.html MySQL索引原理以及查询优化 一.介绍 1.什么是索引? 一般的应用系统,读写比例在10:1左右,而且 ...

  7. mysql 索引原理及查询优化 -转载

    转载自 mysql 索引原理及查询优化 https://www.cnblogs.com/panfb/p/8043681.html 潘红伟   mysql 索引原理及查询优化 一 介绍 为何要有索引? ...

  8. MySQL实验 内连接优化order by+limit 以及添加索引再次改进

    MySQL实验 内连接优化order by+limit 以及添加索引再次改进 在进行子查询优化双参数limit时我萌生了测试更加符合实际生产需要的ORDER BY + LIMIT的想法,或许我们也可以 ...

  9. mysql优化之连接优化(open-files-limit与table_open_cache)

    MySQL打开的文件描述符限制 Can't open file: '.\test\mytable.frm' (errno: 24) OS error code : Too many open file ...

随机推荐

  1. DNS本机可解析,其他主机通过本机无法解析问题

    新建了一个redhat虚拟机,将此虚拟机作为dns服务器使用,配置完以后宿主机的dns服务器设置为配置好的虚拟机地址,结果总是显示no Server Reached,没有服务器可以到达,花了很长时间终 ...

  2. myeclipse过期以后提示过期以后怎么办?!

    昨天电脑上装的myeclipse到期了,不能进到工作空间里边,只有激活和退出选项,在网上百度了一下,有很多破解工具, 1.刚开始直接使用工具破解,没有成功,总是提示要么激活,要么退出 2.继续想办法, ...

  3. C#不能捕捉的异常,如AccessViolationException

    在.net的异常机制中,有部分严重的编程错误(系统的某些Corrupted State Exceptions异常)是默认不被用户使用常规的异常捕捉方式捕捉到的. 微软的这种设计方式,是让用户必须处理该 ...

  4. leecode刷题(16)-- 字符串转换整数

    leecode刷题(16)-- 字符串转换整数 字符串转换整数 描述: 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格 ...

  5. luoguP5068 [Ynoi2015]我回来了

    https://www.luogu.org/problemnew/show/P5068 ynoi 中的良心题啊 考虑用 bitset 来维护里一个点距离小于 $ y_i $ 的点,那么答案就是一堆 b ...

  6. Oauth2.0 整合springCloud的Zuul 解决关键BUG 报错信息:Principal must not be null

    不清楚Oauth2.0 的 可以查看我前几篇博文 2018.4.8 补充 我出现这个原因:是我在资源服务器使用了 如下图所示 Principal Oauth2.0 提供的获取用户信息的方法 使其找到相 ...

  7. php 判断两个时间段是否有交集

    一开始,没啥思路,全靠百度,记录一下哈 public function demo(){ //例子 $astart = strtotime("1995-06-16 12:00:00" ...

  8. php正则验证邮箱、手机号、姓名、身份证、特殊符号等

    1.邮箱验证 1 $email='1515212@qq'; 2 $preg_email='/^[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*@([a-zA-Z0-9]+[-.])+( ...

  9. 那些H5用到的技术(6)——屏幕适配

    前言长屏适配单页适配参考 前言 曾经屏幕适配一直是个头疼的问题,各种坑,各种浏览器&设备兼容问题,好在的是,随着技术&标准的不断发展,这个问题得到了极大程度的解决,这篇文章主要对之前开 ...

  10. Mac下用Launchd实现使用rc.local执行开机启动命令

    其实原理很简单,使用Launchd创建一个开机启动的服务,然后这个服务关联/etc/rc.local文件,那么接下来操作rc.local就和Linux下一样的了. 当然,这种思路还可以直接使用在~/. ...