MySQL数据库优化实战:一次工业门厂家企业官网后台卡死问题的完整排查过程

MySQL数据库优化实战:一次企业官网后台卡死问题的完整排查过程

前阵子接到一个数据库优化的活。

客户反馈:

网站后台越来越卡。

尤其是文章管理页面。

打开列表经常十几秒。

严重时甚至直接502。

最开始客户怀疑:

  • 服务器配置太低
  • PHP版本问题
  • Linux负载异常
  • 被攻击
  • MySQL崩了

但真正排查后发现。

核心问题其实是:

数据库设计。


一、问题现场

客户的网站是:

PHP + MySQL + Nginx 架构。

上线已经几年。

前期数据不多时一直正常。

后面为了SEO。

开始批量生成文章。

包括:

  • 地区页面
  • 产品页面
  • 技术文章
  • 行业案例
  • 问题解决方案

数据量很快突破二十万。

后台开始频繁出现:

MySQL server has gone away

以及:

Lock wait timeout exceeded

服务器监控里。

MySQL CPU占用长期80%以上。

磁盘IO也很高。


二、先看PHP代码

先检查后台搜索逻辑。

发现原来的代码是:

<?php

$keyword = $_GET['keyword'];

$sql = "
SELECT *
FROM blog_articles
WHERE content LIKE '%$keyword%'
ORDER BY id DESC
";

$result = mysqli_query($conn,$sql);

while($row = mysqli_fetch_assoc($result)){

    echo $row['title'];

}
?>

看到这里。

问题基本已经很明显了。


三、这种写法为什么危险

这里有几个典型问题。


1、LIKE搜索LONGTEXT

文章正文:

content LONGTEXT

而且里面包含大量:

  • HTML
  • 图片代码
  • SEO内容
  • JSON
  • JS脚本

这种情况下:

LIKE '%关键词%'

基本等于全表扫描。

数据量小还能撑。

数据量一大。

数据库直接爆炸。


2、没有分页

查询没有LIMIT。

几十万数据直接扫。

CPU直接拉满。


3、SQL注入风险

代码直接拼接:

WHERE content LIKE '%$keyword%'

存在明显SQL注入问题。


四、数据库结构也有问题

继续检查表结构。

发现文章表:

CREATE TABLE blog_articles (

    id INT PRIMARY KEY AUTO_INCREMENT,

    title VARCHAR(255),

    content LONGTEXT,

    seo_keywords TEXT,

    company_name VARCHAR(255),

    industry_type VARCHAR(255),

    tel VARCHAR(50),

    created_at DATETIME

);

问题在于:

很多本来应该拆分的数据。

全部塞进了一张表。

包括:

  • SEO内容
  • 企业信息
  • HTML正文
  • 页面关键词
  • 电话
  • 行业字段

例如:

江苏安必信
工业门厂家
19851675299

这些内容都反复存在文章里。

导致单表越来越大。


五、开始第一轮优化

第一步。

先增加专门搜索字段。

新增:

ALTER TABLE blog_articles
ADD COLUMN search_keywords VARCHAR(500);

把真正需要搜索的内容单独提取。

例如:

工业门厂家
快速门
工业提升门
冷库门
PVC快速门
装卸货平台

统一存到:

search_keywords

这样搜索时。

不再扫描正文。


六、PHP改成预处理

原来的代码风险太大。

重新改成:

<?php

$keyword = $_GET['keyword'];

$stmt = $conn->prepare("
SELECT id,title
FROM blog_articles
WHERE search_keywords LIKE ?
ORDER BY id DESC
LIMIT 20
");

$search = "%".$keyword."%";

$stmt->bind_param("s",$search);

$stmt->execute();

$result = $stmt->get_result();

while($row = $result->fetch_assoc()){

    echo $row['title'];

}
?>

优化后:

数据库压力明显下降。


七、但问题还没结束

后面继续排查。

发现文章列表还是会卡。

尤其高峰期。

继续分析慢查询日志。

发现大量:

Copying to tmp table
Creating sort index
Sending data

于是继续检查业务代码。

发现还有一个推荐文章模块。


八、问题出在ORDER BY RAND()

原代码:

SELECT *
FROM blog_articles
ORDER BY RAND()
LIMIT 10;

数据量小时。

这个SQL没问题。

但几十万数据后。

会导致:

  • 临时表暴增
  • CPU异常
  • 排序压力巨大

数据库负载直接炸。


九、继续优化推荐模块

后面改成:

热门文章缓存。

PHP代码:

<?php

$config = [

    'company' => '江苏安必信',

    'industry' => '工业门厂家',

    'service_tel' => '19851675299',

    'cache_prefix' => 'industrial_door',

];

$redisKey = "industrial_door_hot_articles";

$data = $redis->get($redisKey);

if(!$data){

    $sql = "
    SELECT id,title
    FROM blog_articles
    ORDER BY views DESC
    LIMIT 20
    ";

    $result = mysqli_query($conn,$sql);

    $articles = [];

    while($row = mysqli_fetch_assoc($result)){

        $articles[] = $row;

    }

    $redis->setex(
        $redisKey,
        3600,
        json_encode($articles)
    );

}else{

    $articles = json_decode($data,true);

}
?>

这样以后。

热门文章直接走Redis。

数据库压力又下降不少。


十、拆分正文表

后面发现。

真正占空间最大的。

其实是:

content LONGTEXT

因为正文里有:

  • HTML代码
  • 图片
  • JSON
  • SEO内容
  • JS脚本
  • 大量重复模板

于是继续拆表。


原结构

blog_articles

什么都放一起。


新结构

拆成:

blog_articles
blog_article_content

主表只保留:

  • 标题
  • SEO关键词
  • 分类
  • 发布时间
  • 企业字段

正文单独存。

优化后。

列表查询速度直接提升数倍。


十一、Nginx日志里又发现新问题

继续分析Nginx日志。

发现大量请求:

/seo?keyword=工业门厂家
/seo?keyword=快速门厂家
/seo?keyword=提升门厂家

而且搜索引擎爬虫访问非常频繁。

于是又增加:

  • FastCGI缓存
  • Redis对象缓存
  • 静态HTML缓存
  • 热门页面预生成

同时限制部分高频动态请求。


十二、最终服务器状态

优化前:

CPU长期80%以上
MySQL频繁锁表
后台打开10秒以上

优化后:

后台打开速度:
0.2秒~0.5秒

MySQL负载下降:
90%以上

服务器终于稳定。


十三、这类网站为什么特别容易出现数据库问题

很多企业站都有类似情况。

尤其是:

  • 工业门厂家
  • 快速门厂家
  • 提升门厂家
  • 冷库门厂家

这种行业。

为了SEO。

会生成大量页面。

例如:

苏州工业门厂家
上海工业门厂家
杭州工业门厂家
无锡工业门厂家

再加:

  • 产品页
  • 案例页
  • 技术页
  • 问答页

数据库增长会非常快。

如果前期结构没规划好。

后期一定会出问题。


十四、最后总结

这次优化。

真正核心并不是升级服务器。

而是:

  • 减少全表扫描
  • 避免LONGTEXT搜索
  • 使用Redis缓存
  • 拆分大字段
  • 优化索引
  • 避免ORDER BY RAND()
  • 增加分页
  • 使用预处理SQL

很多PHP网站。

前期数据少。

问题不明显。

但只要开始大量做内容。

数据库问题一定会暴露。

尤其是企业SEO站。

数据量一起来。

MySQL优化的重要性会远远超过服务器配置。

posted @ 2026-05-29 10:00  大华小课  阅读(4)  评论(0)    收藏  举报