MYSQL一次千万级连表查询优化(一)

概述:

交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的功能,这算是离职人员挖下的坑,随着数据越来越多,原本的SQL查询变得越来越慢,用户体验特别差,因此SQL优化任务交到了我手上。 
这个SQL查询关联两个数据表,一个是攻击IP用户表主要是记录IP的信息,如第一次攻击时间,地址,IP等等,一个是IP攻击次数表主要是记录每天IP攻击次数。而需求是获取某天攻击IP信息和次数。(以下SQL语句测试均在测试服务器上上,正式服务器的性能好,查询时间快不少。)

准备:

查看表的行数: 
 
 
未优化前SQL语句为:

SELECT
attack_ip,
country,
province,
city,
line,
info_update_time AS attack_time,
sum( attack_count ) AS attack_times
FROM
`blacklist_attack_ip`
INNER JOIN `blacklist_ip_count_date` ON `blacklist_attack_ip`.`attack_ip` = `blacklist_ip_count_date`.`ip`
WHERE
`attack_count` > 0
AND `date` BETWEEN '2017-10-13 00:00:00'
AND '2017-10-13 23:59:59'
GROUP BY
`ip`
LIMIT 10 OFFSET 1000

先EXPLAIN分析一下: 

这里看到索引是有的,但是IP攻击次数表blacklist_ip_count_data也用上了临时表。那么这SQL不优化直接第一次执行需要多久(这里强调第一次是因为MYSQL带有缓存功能,执行过一次的同样SQL,第二次会快很多。) 

实际查询时间为300+秒,这完全不能接受呀,这还是没有其他搜索条件下的。 
那么我们怎么优化呢,索引既然走了,我尝试一下避免临时表,这时我们先了解一下临时表跟group by的使联系:

查找了网上一些博客分析GROUP BY 与临时表的关系 : 
  1. 如果GROUP BY 的列没有索引,产生临时表. 
  2. 如果GROUP BY时,SELECT的列不止GROUP BY列一个,并且GROUP BY的列不是主键 ,产生临时表. 
  3. 如果GROUP BY的列有索引,ORDER BY的列没索引.产生临时表. 
  4. 如果GROUP BY的列和ORDER BY的列不一样,即使都有索引也会产生临时表. 
  5. 如果GROUP BY或ORDER BY的列不是来自JOIN语句第一个表.会产生临时表. 
  6. 如果DISTINCT 和 ORDER BY的列没有索引,产生临时表.

仔细按照上面分析一下,这SQL可能是因为第二条导致的,blacklist_ip_count_date这个表的确主键不是IP,SELECT是多列的,那么我们试试单独提出单表测试能不能避免临时表: 

很遗憾,并不能避免,但是我们仔细看看这EXPLAIN 里面的KEY 分析,用的索引是date单字段的索引。这好像就是导致了第一条的问题了,相当于GROUP BY没有用索引。那么我们试试强制使用IP单字段的索引呢? 

这里看来的确是索引的问题,导致了临时表啊,然而再看看ROWS的数量,原来的9W变成了1552W,这不是不是捡了芝麻掉了西瓜吗? 
这里单列索引 避免了临时表可是联系的行数又增加了,那么我们再试试复合索引呢? 
于是创建attack_count、date、ip的复合索引index_Acount_date_ip 

ROWS的行数770W而且还是有临时表,看来这复合索引也是不可取。 
到此,避免临时表方法失败了,我们得从其他角度想想如何优化。 
其实,9W的临时表并不算多,那么为什么导致会这么久的查询呢?我们想想这没优化的SQL的执行过程是怎么样的呢?

网上搜索得知内联表查询一般的执行过程是:
1、执行FROM语句
2、执行ON过滤
3、添加外部行
4、执行where条件过滤
5、执行group by分组语句
6、执行having
7、select列表
8、执行distinct去重复数据
9、执行order by字句
10、执行limit字句
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这里得知,Mysql 是先执行内联表然后再进行条件查询的最后再分组,那么想想这SQL的条件查询和分组都只是一个表的,内联后数据就变得臃肿了,这时候再进行条件查询和分组是否太吃亏了,我们可以尝试一下提前进行分组和条件查询,实现方法就是子查询联合内联查询。 

这里EXPLAIN看来,只是多了子查询,ROWS和临时表都没有变化。那么我们看看实际的效果呢? 

可见,取出来的数据完全一模一样,可是优化后效率从原来的330秒变成了0.28秒,这里足足提升了1000多倍的速度。这也基本满足了我们的优化需求。

mysql千万级表关联优化的更多相关文章

  1. mysql千万级表关联优化(2)

    概述: 交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的功能,这算是离职人员挖下的坑,随着数据越来越多,原本的SQL查询变得越来越慢,用户体验特别差,因此SQL优化任务交到了我手上. 这个 ...

  2. 如何优化MySQL千万级大表

    很好的一篇博客,转载 如何优化MySQL千万级大表 原文链接::https://blog.csdn.net/yangjianrong1985/article/details/102675334 千万级 ...

  3. Mysql千万级大表优化

    Mysql的单张表的最大数据存储量尚没有定论,一般情况下mysql单表记录超过千万以后性能会变得很差.因此,总结一些相关的Mysql千万级大表的优化策略. 1.优化sql以及索引 1.1优化sql 1 ...

  4. MySQL千万级大表优化解决方案

    MySQL千万级大表优化解决方案 非原创,纯属记录一下. 背景 无意间看到了这篇文章,作者写的很棒,于是乎,本人自私一把,把干货保存下来.:-) 问题概述 使用阿里云rds for MySQL数据库( ...

  5. MySQL 百万级分页优化(Mysql千万级快速分页)(转)

    http://www.jb51.net/article/31868.htm 以下分享一点我的经验 一般刚开始学SQL的时候,会这样写 复制代码 代码如下: SELECT * FROM table OR ...

  6. MySQL 百万级分页优化(Mysql千万级快速分页)

    以下分享一点我的经验 一般刚开始学SQL的时候,会这样写 : SELECT * FROM table ORDER BY id LIMIT 1000, 10; 但在数据达到百万级的时候,这样写会慢死 : ...

  7. 如何优化Mysql千万级快速分页,limit优化快速分页,MySQL处理千万级数据查询的优化方案

    如何优化Mysql千万级快速分页,limit优化快速分页,MySQL处理千万级数据查询的优化方案

  8. mysql千万级数据库插入速度和读取速度的调整记录

    一般情况下mysql上百万数据读取和插入更新是没什么问题了,但到了上千万级就会出现很慢,下面我们来看mysql千万级数据库插入速度和读取速度的调整记录吧. 1)提高数据库插入性能中心思想:尽量将数据一 ...

  9. 如何对MySQL 对于大表(千万级)进行优化

    如何对Mysql中的大型表进行优化 @(mysql 笔记) 收集信息 1.数据的容量:1-3年内会大概多少条数据,每条数据大概多少字节: 2.数据项:是否有大字段,那些字段的值是否经常被更新: 3.数 ...

随机推荐

  1. jQuery读取KindEditor的值

    $(document.getElementsByTagName("iframe")[0].contentWindow.document.body).html();

  2. vue2.0实战记录

    1. 初始化项目vue init webpack caseone cd caseonecnpm installcnpm install less less-loader -Dcnpm install ...

  3. RabbitMQ消息队列里积压很多消息

    1.场景:上千万条消息在mq里积压了几个小时了还没解决 2.解决: 1)先修复consumer的问题,确保其恢复消费速度,然后将现有cnosumer都停掉 2)新建一个topic,partition是 ...

  4. RTSP服务器之————rtsp-server(轻量级RTSP / RTP流媒体服务器)

    github:https://github.com/revmischa/rtsp-server 轻量级RTSP / RTP流媒体服务器

  5. java selenium常用API(WebElement、iFrame、select、alert、浏览器窗口、事件、js) 一

     WebElement相关方法 1.点击操作 WebElement button = driver.findElement(By.id("login")); button.clic ...

  6. 关于安装在win10上的oracle10g 兼容性问题

    首先在安装过程中会出现一次报错,在安装的时候 安装好了以后,准备敲击命令如果出现闪退,即是兼容性问题,下面继续设置兼容性问题 然后右键----属性----兼容性,勾上以兼容性运行即可

  7. Javascript 常用的工具函数,更新中...

    1.时间戳转为格式化时间 /** * 时间戳转为格式化时间 * @Author chenjun * @DateTime 2017-11-10 * @param {[date]} timestamp [ ...

  8. 有用的Javascript,长期更新...

    1,点击目标区域以外隐藏,运用场景:点击遮罩层,弹层关闭. // 点击目标区域以外隐藏 $(document).on("click", function (event) { var ...

  9. JS设计模式——7.工厂模式(示例-RSS阅读器)

    RSS阅读器 由于我们只想跟RSS容器对象打交道,所以用一个工厂来实例化这些内部对象并把它们组装到一个RSS阅读器中. 使用工厂方法在好处在于,我们创建的RSS阅读器类不会与那些成员对象紧密耦合在一起 ...

  10. cdn_一些常用的cdn地址

    https://code.jquery.com/jquery-3.3.1.jshttps://cdn.bootcss.com/jquery/2.1.4/jquery.min.js https://cd ...