就在本周,应该是在本周二,小编翻车啦~~~

之前有关注我的同学应该知道,小编在国庆节写了一只爬虫,来抓取自己的各个平台博客的访问量等一些数据,并且后面简单做了个报表,主要是靠 SQL 来统计数据。

这只爬虫小编部署到 Linux 服务器上以后,设置了整点定时抓取数据也没管过,倒是刚上线那段时间经常去报表平台看看统计报表。

想了解事情起因的同学可以看一下这两篇文章

肯定哪里不对,小编赶紧用 Navicat 执行了一下报表的 SQL ,结果:

对的,你没看错,这句话执行了 20s+ ,小编当时的心里感觉有一万只羊驼奔腾而过。

有没有搞错,数据拢共 2k 多条,执行一下要 20s+ ,是在开玩笑么,小编当时都怀疑自己是不是用了一台假数据库。

emmmmmmmmmm,顺便介绍一下数据库配置,使用的是某云服务的 MySQL 库,硬件配置为 1H1G(1核1G)。

冷静下,深呼吸两个,小编不信邪,正好手上有一台 2H8G 的服务器,赶紧搭一个 Mysql 试一下,某云提供的一定是假数据库。

结果,emmmmmmmmmmm,还是直接给各位同学看吧。

好吧,现在要正式这个错误。。。

不过服务器的核心数加了一倍(一个)时间数少了一半多,那理论上讲,如果小编用的是一台物理机,如果这台物理机有大几十核的 CPU ,就不会有问题啊~~~

果然,还是贫穷惹的祸。。。。

告辞。

当然,本文不会就这么结束:)

现在,已经发现错误了,接下来就是尤为关键的一步了,解决这个问题。

程序猿解决问题是有一个万能的模版,先用这个模版套一下:

emmmmmmmmmm,提问题的人是小编自己,所以,小编不能解决掉自己,那么,这就不是个问题,所以也就不需要解决了。。。。。。。。

不行,这个还是太影响使用体验,还是来正经的分析下这个问题。

首先看下数据库的表设计:

咳咳。

就这么一张表,当时比较懒,爬虫每次抓取的都是当时的截面数据,统计报表的 sql 需要动态的去算出每天的增量数据。具体算法是使用当天的最大值减去前一天的最大值,再进行分类统计。

看下小编的 sql 吧:

SELECT a.read_num - (         SELECT b.read_num         FROM spider_data b         WHERE b.plantform = a.plantform             AND DATE_FORMAT(b.create_date, '%Y-%m-%d') = date_sub(DATE_FORMAT(a.create_date, '%Y-%m-%d'), INTERVAL 1 DAY)          ORDER BY b.create_date DESC LIMIT 1     ) AS read_num, a.fans_num - (         SELECT b.fans_num         FROM spider_data b         WHERE b.plantform = a.plantform             AND DATE_FORMAT(b.create_date, '%Y-%m-%d') = date_sub(DATE_FORMAT(a.create_date, '%Y-%m-%d'), INTERVAL 1 DAY)         ORDER BY b.create_date DESC LIMIT 1     ) AS fans_num     , a.like_num - (         SELECT b.like_num         FROM spider_data b         WHERE b.plantform = a.plantform             AND DATE_FORMAT(b.create_date, '%Y-%m-%d') = date_sub(DATE_FORMAT(a.create_date, '%Y-%m-%d'), INTERVAL 1 DAY)         ORDER BY b.create_date DESC LIMIT 1     ) AS like_num, (         SELECT b.rank_num         FROM spider_data b         WHERE b.plantform = a.plantform             AND DATE_FORMAT(b.create_date, '%Y-%m-%d') = date_sub(DATE_FORMAT(a.create_date, '%Y-%m-%d'), INTERVAL 1 DAY)         ORDER BY b.create_date DESC LIMIT 1     ) - a.rank_num AS rank_num     , a.create_date,a.plantform FROM (SELECT * FROM spider_data ORDER BY create_date DESC LIMIT 1000000000000000) a  GROUP BY DATE_FORMAT(a.create_date, '%Y-%m-%d'), a.plantform ORDER BY a.create_date DESC;

稍微长了一丢丢,不过从这个 sql 上,已经能看到明显的问题了,在做查询的时候,使用了大量的子查询。

至于为什么要这么写,当然是因为懒咯~~~

前面的爬虫已经将截面数据爬取到了,后面做统计当然是一句话搞定了。

结果就是这偷懒的一句话,酿造了今天的惨剧。