生成环境的 a 表有一条慢 sql,需要为其建立一个索引。由于其表有一亿多条数据,索引不能直接在生产环境创建,所以想到的方案是创建一个跟 a 表结构相同的 b 表,并在 b 表上创建需要的索引,然后将 a 表的数据批量插入到 b 表。前段时间由于一些表不再满足业务需求,需要把主键的类型由 int 改为 bigint,同事写了一个在线上切换大表的脚本,我仿照着写了一个简单的更改一个表的。考虑到以后还可能遇到这种场景,所以把脚本记录于此。
/** @var Model $model */ $model = M(''); $sql = "SELECT max(id) FROM b";// 获取已经同步的条数 $synced_id = $model->getField($sql) ?: 0;
$limit = 100000;// 每个插入的条数 $start = $synced_id; while (time() < $deadline) { $sql = "SELECT id FROM a WHERE id > {$start} LIMIT 1"; if (empty($model->getField($sql))) { sleep(3); continue; }
$step = $start + $limit; $sql = "INSERT INTO b SELECT * FROM a WHERE id > {$start} AND id <= {$step}"; $model->query($sql); $start = $step;