宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見(jiàn)問(wèn)題
產(chǎn)品動(dòng)態(tài)
精選推薦

用戶表單有200w用戶導(dǎo)致后臺(tái)用戶列表打不開(kāi),日志記錄sql查詢

管理 管理 編輯 刪除

這個(gè)情況其實(shí)是 MySQL 查詢?cè)O(shè)計(jì)和索引使用問(wèn)題導(dǎo)致的典型性能瓶頸


我們先分析一下你的 SQL、瓶頸原因,再講優(yōu)化思路,最后給出幾種實(shí)用的解決方案。??


一、SQL 性能瓶頸分析

你的慢 SQL:

SELECT COUNT(*) AS think_count 
FROM (
  SELECT count(*) AS think_count 
  FROM `eb_user` `u`
  LEFT JOIN `eb_wechat_user` `w` ON `u`.`uid` = `w`.`uid`
  GROUP BY `u`.`uid`
) `_group_count_`

問(wèn)題點(diǎn):

  1. GROUP BY + COUNT 嵌套子查詢: 內(nèi)層 GROUP BY 會(huì)對(duì) 200w 用戶執(zhí)行一次分組,再計(jì)算每組數(shù)量,生成臨時(shí)表,代價(jià)極高。
  2. LEFT JOIN: eb_wechat_user 若也有大量記錄,JOIN 會(huì)放大數(shù)據(jù)量,尤其當(dāng)索引不合理時(shí)。
  3. 外層 COUNT(): 實(shí)際只需要統(tǒng)計(jì)行數(shù),卻先讓內(nèi)層生成完整的 200w 分組結(jié)果。
  4. 沒(méi)有用索引覆蓋: 如果 u.uid 或 w.uid 沒(méi)有合適索引,MySQL 只能全表掃描 + 文件排序。

結(jié)果:執(zhí)行時(shí)間 32.7 秒,非常合理(對(duì)于200萬(wàn)行 JOIN + GROUP BY)。

二、MySQL 執(zhí)行邏輯簡(jiǎn)化圖

eb_user (200w) ---LEFT JOIN--> eb_wechat_user (~200w)
      |                  |
      |                  |
      +---> 按 uid 分組 -> 臨時(shí)表 -> 外層 COUNT(*)

每個(gè)階段都在全表掃描,磁盤(pán)IO、排序、分組都耗時(shí)。

三、優(yōu)化方向

1. 去掉不必要的子查詢

如果只是想統(tǒng)計(jì)用戶數(shù)量,其實(shí)根本不需要子查詢:

SELECT COUNT(DISTINCT u.uid)
FROM eb_user u
LEFT JOIN eb_wechat_user w ON u.uid = w.uid;

這條語(yǔ)句能直接用索引優(yōu)化。

2. 確保關(guān)鍵字段有索引

確保下面的索引存在:

ALTER TABLE eb_user ADD INDEX idx_uid(uid);
ALTER TABLE eb_wechat_user ADD INDEX idx_uid(uid);

如果 uid 已經(jīng)是主鍵,就不用加。

3. 不用 LEFT JOIN 時(shí)改為 INNER JOIN

如果邏輯上允許(比如每個(gè)用戶在 wechat 表中必定有記錄):

SELECT COUNT(DISTINCT u.uid)
FROM eb_user u
JOIN eb_wechat_user w ON u.uid = w.uid;

INNER JOINLEFT JOIN 快得多(MySQL 優(yōu)化器可提前剪枝)。

4. 避免實(shí)時(shí) COUNT 大表

后臺(tái)列表一般只需展示分頁(yè)數(shù)據(jù)和總數(shù),可以:

  • 分頁(yè)查詢 + 預(yù)估總數(shù) SELECT * FROM eb_user LIMIT 0, 20; 總數(shù)通過(guò)緩存或定時(shí)任務(wù)更新。
  • 或使用 EXPLAIN + 查詢緩存表 每隔5分鐘更新一次 user_count 緩存表,前端不實(shí)時(shí)查 COUNT。

5. 調(diào)整 SQL 寫(xiě)法讓優(yōu)化器可用索引

MySQL 優(yōu)化器對(duì) COUNT(DISTINCT) + 索引優(yōu)化很敏感。

-- 優(yōu)化版 1:直接使用 DISTINCT
SELECT COUNT(DISTINCT u.uid)
FROM eb_user u
LEFT JOIN eb_wechat_user w ON u.uid = w.uid;
-- 優(yōu)化版 2:只查主表統(tǒng)計(jì)
SELECT COUNT(*) FROM eb_user;

如果業(yè)務(wù)上只統(tǒng)計(jì)用戶總數(shù),這條最快

6. 分頁(yè)數(shù)據(jù)展示時(shí)優(yōu)化 JOIN

后臺(tái)用戶列表只需顯示部分字段,可以:

SELECT u.uid, u.nickname, w.openid
FROM eb_user u
LEFT JOIN eb_wechat_user w ON u.uid = w.uid
ORDER BY u.uid DESC
LIMIT 0, 20;

再加上:

ALTER TABLE eb_user ADD INDEX idx_uid_desc(uid DESC);

四、針對(duì) ThinkPHP 場(chǎng)景(你的 SQL 日志看起來(lái)是 ThinkPHP 生成的)

如果你用的是 ThinkPHP ORM:

問(wèn)題代碼示例

Db::name('user')
  ->alias('u')
  ->leftJoin('wechat_user w', 'u.uid=w.uid')
  ->count();

ThinkPHP 會(huì)生成你貼的那種“二層 COUNT”語(yǔ)句。

解決方法

直接使用:

Db::query("SELECT COUNT(DISTINCT u.uid) as total FROM eb_user u LEFT JOIN eb_wechat_user w ON u.uid=w.uid");

Db::name('user')->count(); // 僅統(tǒng)計(jì)主表數(shù)量

五、如果確實(shí)需要統(tǒng)計(jì)JOIN分組數(shù)量

那就使用 臨時(shí)表 + 預(yù)聚合方案

CREATE TABLE user_wechat_summary AS
SELECT u.uid, COUNT(w.uid) AS wechat_count
FROM eb_user u
LEFT JOIN eb_wechat_user w ON u.uid = w.uid
GROUP BY u.uid;

然后后臺(tái)查詢直接:

SELECT COUNT(*) FROM user_wechat_summary;

通過(guò)定時(shí)任務(wù)每晚刷新一次這個(gè)表,性能可以提升百倍以上。


六、總結(jié)優(yōu)化建議清單

問(wèn)題優(yōu)化方案
查詢結(jié)構(gòu)嵌套 COUNT改為 COUNT(DISTINCT)
JOIN 未建索引uid 加索引
LEFT JOIN 無(wú)必要改成 INNER JOIN
COUNT 大表慢改成緩存統(tǒng)計(jì)
GROUP BY 全表掃描預(yù)聚合中間表
ORM 自動(dòng)生成的復(fù)雜 SQL改寫(xiě)為原生 SQL


針對(duì) 200w 用戶列表的分頁(yè)+緩存方案(含 SQL + ThinkPHP 實(shí)現(xiàn)示例)

請(qǐng)登錄后查看

小碼二開(kāi) 最后編輯于2025-10-24 10:03:13

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點(diǎn)贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}} 【已收集】
{{item.floor}}# 沙發(fā) 板凳 地板 {{item.floor}}# 【已收集】
{{item.user_info.title || '暫無(wú)簡(jiǎn)介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
分享
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
254
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
回復(fù)
回復(fù)
問(wèn)題:
問(wèn)題自動(dòng)獲取的帖子內(nèi)容,不準(zhǔn)確時(shí)需要手動(dòng)修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請(qǐng)輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊(cè)

切換手機(jī)號(hào)登錄

{{ bind_phone ? '綁定手機(jī)' : '手機(jī)登錄'}}

{{codeText}}
切換微信登錄/注冊(cè)
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開(kāi)源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服