DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

2017年12月2日上午,将学校新闻网2015年之前的45000多条记录迁移到了新网站的mysql数据库,新网站上有2015年1月1日之后的9000多条记录,数据量一下子增加了5倍。 
2017年12月3日晚上9点多,有领导和老师反映新闻网无法访问,立即登录服务器进行排查。 

一、使用top命令看到的情况如下: 
 
可以看到服务器负载很高,,mysql CPU使用已达到接近400%(因为是四核,所以会有超过100%的情况)。 

二、在服务器上执行mysql -u root -p之后,输入show full processlist; 可以看到正在执行的语句。 

可以看到是下面的SQL语句执行耗费了较长时间。 

SELECT id,title,most_top,view_count,posttime FROM article 
where status=3 AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17)  
order by most_top desc,posttime desc limit 0,8 
但是从数据库设计方面来说,该做的索引都已经做了,SQL语句似乎没有优化的空间。

直接执行此条SQL,发现速度很慢,需要1-6秒的时间(跟mysql正在并发执行的查询有关,如果没有并发的,需要1秒多)。如果把排序依据改为一个,则查询时间可以缩短至0.01秒(most_top)或者0.001秒(posttime)。 

三、修改mysql配置文件中的pool/buffer等数值,重启mysql都没有作用。 

四、通过EXPLAIN分析SQL语句 

EXPLAIN SELECT id,title,most_top,view_count,posttime FROM article 
where status=3 AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17)  
order by most_top desc,posttime desc limit 0,8 
可以看到,主select对27928条记录使用filesort进行了排序,这是造成查询速度慢的原因。然后8个并发的查询使CPU专用很高。
 
五、优化
首先是缩减查询范围
SELECT id,title,most_top,view_count,posttime FROM article 
where status=3 AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17)  and DATEDIFF(NOW(),posttime)<=90
order by most_top desc,posttime desc limit 0,8
发现有一定效果,但效果不明显,原因是每条记录都要做一次DATEDIFF运算。后改为
SELECT id,title,most_top,view_count,posttime FROM article 
where status=3 AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17)  and postime>='2017-09-05'
order by most_top desc,posttime desc limit 0,8
查询速度大幅提高。在PHP中,日期阈值通过计算得到
$d = date("Y-m-d", strtotime('-90 day'));
$sql = "
SELECT id,title,most_top,view_count,posttime FROM article 
where status=3 AND catalog_id in (select catalog_id from catalog where catalog_id=17 or parent_id=17)  and postime>='$d'
order by most_top desc,posttime desc limit 0,8
"
 
六、效果
查询时间大幅度缩短,CPU负载很轻
 

 

posted on   DoubleLi  阅读(1521)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2019-01-21 vld for memory leak detector (release version)
2019-01-21 在Release版本下使用VLD
2015-01-21 CURL 和LIBCURL C++代码 上传本地文件,好不容易碰到了这种折腾我几天的代码
2014-01-21 VS2008调试技巧收集备用
2013-01-21 c++读写文件和测试程序运行时间的例子
2013-01-21 vc ++ 如何做界面开发?
2013-01-21 VCRedist.exe静默安装方法
点击右上角即可分享
微信分享提示