学生同步稳态只写变更行
实测写入才是大头,不是平台拉取:9.8 万行的表上 800 行/批 upsert 要 716ms, 123 批共 88 秒;而窄读全部 (xh, row_hash) 只要 2.1 秒。 做法: - gxmu_student 增列 row_hash,存放「平台权威字段」的 MD5 指纹 (迁移 sql/20260915_add_student_row_hash.sql,可重复执行) - 同步时先窄读现有指纹,只 upsert 指纹变化的行 - 窄读同时服务于停用差集,省掉原先单独的一次 selectAllXh - deactivateByXh 顺带把 row_hash 置空,保证停用行以后重新出现时一定被重新写入 指纹规则单独成类 StudentFingerprint:它必须与 mapper 的 ON DUPLICATE KEY UPDATE 子句严格对应——往 UPDATE 里加字段却忘了加进指纹, 那一列就会静默地不再更新,这类 bug 不报错、只产生过期数据。 因此附有逐字段的测试,并由 MapperFieldWhitelistTest 守住 UPDATE 子句本身。 附带收益:未变更的行不再刷新 update_time,该字段恢复「最后变更时间」的含义; 码表修正后 nation/politics 变化会触发自动重算,正是 ADR-0006 承诺的行为。 预期学生同步 170 秒 -> 约 85 秒,其中写库 88 秒 -> 约 2 秒。 现有 98187 行 row_hash 为空,部署后第一次仍会全量写一次。 离线单测 50 个。
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
-- ============================================================================
|
||||
-- 学生名册变更指纹:稳态只写变更行
|
||||
--
|
||||
-- 背景:gxmu_student 已有 9.8 万行时,一次全量 upsert 实测 88 秒(800 行/批 716ms × 123 批),
|
||||
-- 而窄读全部 (xh, row_hash) 只要 2.4 秒。多数行每天并不变化,没必要每天重写一遍。
|
||||
-- 做法:把「平台权威字段」拼成一个指纹存在 row_hash 里,同步时先窄读现有指纹,
|
||||
-- 只 upsert 指纹变化的行。
|
||||
--
|
||||
-- 附带好处:未变更的行不再被刷新 update_time,该字段恢复其「最后真正变更时间」的含义。
|
||||
--
|
||||
-- 可重复执行
|
||||
-- ============================================================================
|
||||
|
||||
SET @exist := (SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'gxmu_student'
|
||||
AND COLUMN_NAME = 'row_hash');
|
||||
SET @stmt := IF(@exist = 0,
|
||||
'ALTER TABLE `gxmu_student` ADD COLUMN `row_hash` VARCHAR(32) NULL COMMENT ''平台权威字段指纹,用于跳过未变更行'' AFTER `deleted`',
|
||||
'SELECT 1');
|
||||
PREPARE s FROM @stmt; EXECUTE s; DEALLOCATE PREPARE s;
|
||||
Reference in New Issue
Block a user