萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 分庫分表與不停機變更表結構實戰:千萬級用戶表優化實錄

場景:單表 1000 萬+ 記錄查詢緩慢

用戶表 members 單表過大,查詢效能瓶頸。採用**分表**策略:按 mid % 100 拆分為 members_00 ~ members_99 共 100 張結構相同的表。

分表資料遷移腳本

";
    // 分批寫入,避免單次事務過大
    echo "INSERT INTO members_{$i} SELECT * FROM members WHERE mid % 100 = {$i} LIMIT 50000;
"; } ?>
  • 分批 LIMIT 50000 寫入,控制事務大小、減少鎖持有時間。
  • 若有自增主鍵衝突,需先處理 ID 空間分配(如雪花演算法、區段預留)。

不停機變更表結構(Online DDL 思想)

同樣是 members 表,需調整結構(如刪減冗餘欄位、調整索引),且不能停機。

步驟

  1. 建立臨時表:
    CREATE TABLE members_tmp LIKE members;
  2. 修改臨時表結構:
    ALTER TABLE members_tmp ...(加/減欄位、調索引、改型別)。
  3. 分批同步歷史資料:
    用上述分批 INSERT ... SELECT 將舊資料導入 members_tmp(可併發多線程跑)。
  4. 同步增量資料:
    開啟 binlog,或應用層雙寫,將遷移期間的新增/變更同步到 members_tmp。
  5. 原子切換:
    RENAME TABLE members TO members_bak, members_tmp TO members;
    RENAME TABLE 是原子操作,僅持有極短元資料鎖,業務幾乎無感知。
  6. 驗證與清理:
    確認新表正常後,觀察一段時間再 DROP TABLE members_bak。

實際效果

  • 原表 8GB+ → 優化後 2GB+,空間壓縮 75%。
  • 查詢延遲從秒級降至毫秒級。
  • 全程業務無停機,僅 RENAME 瞬間極短鎖定。

避坑提醒

  • RENAME TABLE 雖快,但會阻塞所有對該表的 DML,選擇低峰期執行。
  • 分表後應用層需引入路由邏輯(mid % 100),或使用中間件(ShardingSphere、MyCat、Vitess)。
  • Float/Double 型別作為查詢條件極不靠諜(精度問題),金額/精確數值**堅決用 DECIMAL**。
copyright © 萬盛學電腦網 all rights reserved