首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 游標批量處理實戰:動態遍歷百表同步建索引/加欄位

     編輯:MySQL 資料庫相關知識

前置知識鏈接

游標四大核心操作


-- 1. 聲明
DECLARE cursor_name CURSOR FOR SELECT 语句;

-- 2. 打開
OPEN cursor_name;

-- 3. 推進/取值
FETCH cursor_name INTO var1, var2...;

-- 4. 關閉
CLOSE cursor_name;
注意:SELECT 不能含 INTO 子句;需聲明 NOT FOUND 條件處理器避免越界報錯。

實戰場景:百張同結構表批量加索引

業務按月分表:student_202301 ~ student_202312,需為每張表同步建立 5 條索引。

完整存儲過程


DROP PROCEDURE IF EXISTS BatchAddIndex;
DELIMITER $$
CREATE PROCEDURE BatchAddIndex()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE tbl_name VARCHAR(64);
    
    -- 聲明游標:查詢前綴為 student_ 的表
    DECLARE cur CURSOR FOR 
        SELECT TABLE_NAME 
        FROM information_schema.TABLES 
        WHERE TABLE_SCHEMA = 'front' 
          AND TABLE_NAME LIKE 'student%';
    
    -- 邊界處理:游標耗盡設置 done=TRUE
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    OPEN cur;
    
    read_loop: LOOP
        FETCH cur INTO tbl_name;
        IF done THEN
            LEAVE read_loop;
        END IF;
        
        -- 動態構建 5 條建索引 SQL
        SET @sql1 = CONCAT('CREATE INDEX idx_flag ON `', tbl_name, '` (flag)');
        SET @sql2 = CONCAT('CREATE INDEX idx_state ON `', tbl_name, '` (state)');
        SET @sql3 = CONCAT('CREATE INDEX idx_upload ON `', tbl_name, '` (upload)');
        SET @sql4 = CONCAT('CREATE INDEX idx_lockflag ON `', tbl_name, '` (lockFlag)');
        SET @sql5 = CONCAT('CREATE INDEX idx_comes ON `', tbl_name, '` (comes)');
        
        -- 預處理 + 執行 + 釋放(逐條執行,便於定位失敗)
        PREPARE s1 FROM @sql1; EXECUTE s1; DEALLOCATE PREPARE s1;
        PREPARE s2 FROM @sql2; EXECUTE s2; DEALLOCATE PREPARE s2;
        PREPARE s3 FROM @sql3; EXECUTE s3; DEALLOCATE PREPARE s3;
        PREPARE s4 FROM @sql4; EXECUTE s4; DEALLOCATE PREPARE s4;
        PREPARE s5 FROM @sql5; EXECUTE s5; DEALLOCATE PREPARE s5;
        
    END LOOP;
    
    CLOSE cur;
END $$
DELIMITER ;

CALL BatchAddIndex();

關鍵技術點解析

1. 為什麼要用 PREPARE?

存儲過程中變量不能直接作為表名/列名使用,必須動態拼接 SQL 字符串,再通過預處理執行。

2. CONTINUE HANDLER vs EXIT HANDLER

  • CONTINUE:游標結束後繼續執行後續邏輯(本例適用)
  • EXIT:直接退出當前 BEGIN...END 塊

3. 批量 DDL 風險控制

  • 生產環境慎用: 鎖表時間長、易引發主從延遲
  • 建議:低峰期執行、分批次、配合 pt-online-schema-change
  • 執行前必備:完整備份、驗證回滾腳本

擴展場景

  • 批量加欄位:ALTER TABLE ... ADD COLUMN ...
  • 批量修改字符集:ALTER TABLE ... CONVERT TO CHARSET utf8mb4
  • 批量刪除廢棄索引:DROP INDEX ... ON ...
  • 跨庫同步:游標查 information_schema.SCHEMATA 雙層循環

總結

游標 + 預處理 = MySQL 服務端動態批量 DDL 的標準解法。
威力巨大,風險同在。**生產環境三思而後行,預演環境全流程驗證。**
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved