| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- -- 1.0.321.sql S2 排程性能 L1:齐套检查/BOM 展开热点路径补齐二级索引。
- -- 背景:EXPLAIN ANALYZE 实测 ic_bom_child 子件查询扫 59,799+22,108 行、服务端 103ms;
- -- InvMaster 库存查询扫 18,368 行、17.9ms。二者均为全表扫描(无可用索引)。
- -- 本脚本只建【非唯一】二级索引 + 一个主键,不改字段类型/可空性,不增删改任何业务数据,
- -- 不删除任何现有索引。因此不存在数据冲突导致失败的可能,无需前置去重。
- -- 索引列依据见 doc/plan/S2排程性能-L1索引体系执行任务书.md §2.4(逐条对应实际查询条件)。
- -- ============================================================================
- -- ========== 〇、通用幂等宏说明 ==========
- -- 每个索引统一走:查 information_schema.STATISTICS 判是否已存在 -> 不存在才 ADD。
- -- 重复执行本脚本不会报错,也不会重复创建。
- -- ========== 一、ic_bom_child(59,799 行,当前零索引含主键) ==========
- -- 1.1 主键。已实证 Id 全部唯一且非空(59799/59799,null=0);
- -- 且全仓库无任何应用侧 INSERT 写该表(仅 MaterialRequirementCalculator 的 SELECT),
- -- 不会因新主键产生重复键失败。
- SET @has_pk := (SELECT COUNT(*) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom_child' AND INDEX_NAME = 'PRIMARY');
- SET @sql := IF(@has_pk = 0,
- 'ALTER TABLE ic_bom_child ADD PRIMARY KEY (Id)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- 1.2 主查询路径:WHERE bom_id=? AND tenant_id=? AND IsDeleted=0
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom_child'
- AND INDEX_NAME = 'idx_ic_bom_child_tenant_bom');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE ic_bom_child ADD INDEX idx_ic_bom_child_tenant_bom (tenant_id, bom_id, IsDeleted)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- 1.3 反查父阶 / 按物料查用量
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom_child'
- AND INDEX_NAME = 'idx_ic_bom_child_tenant_item');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE ic_bom_child ADD INDEX idx_ic_bom_child_tenant_item (tenant_id, item_number)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ========== 二、ItemMaster(22,108 行) ==========
- -- 现有 uk_ItemMaster_factory_item (tenant_id, factory_ref_id, ItemNum) 因中间缺 factory_ref_id
- -- 无法服务 BOM 子件关联,补 (tenant_id, ItemNum)。不动现有唯一索引。
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ItemMaster'
- AND INDEX_NAME = 'idx_ItemMaster_tenant_item');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE ItemMaster ADD INDEX idx_ItemMaster_tenant_item (tenant_id, ItemNum)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ========== 三、ic_bom(5,431 行) ==========
- -- 3.1 ResolveBomIdByItemAsync:WHERE tenant_id=? AND IsDeleted=0 AND item_number=?
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom'
- AND INDEX_NAME = 'idx_ic_bom_tenant_item');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE ic_bom ADD INDEX idx_ic_bom_tenant_item (tenant_id, item_number, IsDeleted)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- 3.2 ResolveBomIdAsync 的 bom_number 分支
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom'
- AND INDEX_NAME = 'idx_ic_bom_tenant_bomnum');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE ic_bom ADD INDEX idx_ic_bom_tenant_bomnum (tenant_id, bom_number)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ========== 四、InvMaster(18,368 行) ==========
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'InvMaster'
- AND INDEX_NAME = 'idx_InvMaster_tenant_item');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE InvMaster ADD INDEX idx_InvMaster_tenant_item (tenant_id, ItemNum)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ========== 五、PurOrdDetail(95 行,为将来增长预留) ==========
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'PurOrdDetail'
- AND INDEX_NAME = 'idx_PurOrdDetail_item_ord');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE PurOrdDetail ADD INDEX idx_PurOrdDetail_item_ord (ItemNum, PurOrdRecID)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ========== 六、ic_item_stockoccupy(497 行;排程起始 DELETE + 占用汇总) ==========
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_item_stockoccupy'
- AND INDEX_NAME = 'idx_ic_item_stockoccupy_tenant_bang');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE ic_item_stockoccupy ADD INDEX idx_ic_item_stockoccupy_tenant_bang (tenant_id, bang_id, IsDeleted)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ========== 七、b_bom_child_examine(8,679 行,齐套结果明细) ==========
- -- examine_id 必须最左:ResourceCheckResultWriter 的 UPDATE 只带 examine_id、不带 tenant_id。
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'b_bom_child_examine'
- AND INDEX_NAME = 'idx_b_bom_child_examine_examine');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE b_bom_child_examine ADD INDEX idx_b_bom_child_examine_examine (examine_id, tenant_id, is_use)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ========== 八、b_examine_result(279 行,齐套结果头) ==========
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'b_examine_result'
- AND INDEX_NAME = 'idx_b_examine_result_tenant_entry');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE b_examine_result ADD INDEX idx_b_examine_result_tenant_entry (tenant_id, sentry_id, IsDeleted)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'b_examine_result'
- AND INDEX_NAME = 'idx_b_examine_result_tenant_morder');
- SET @sql := IF(@has_ix = 0,
- 'ALTER TABLE b_examine_result ADD INDEX idx_b_examine_result_tenant_morder (tenant_id, morder_no)', 'DO 0');
- PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
- -- ========== 九、刷新统计信息,让优化器立刻用上新索引 ==========
- ANALYZE TABLE ic_bom_child;
- ANALYZE TABLE ItemMaster;
- ANALYZE TABLE ic_bom;
- ANALYZE TABLE InvMaster;
- ANALYZE TABLE PurOrdDetail;
- ANALYZE TABLE ic_item_stockoccupy;
- ANALYZE TABLE b_bom_child_examine;
- ANALYZE TABLE b_examine_result;
- -- ============================================================================
- -- 回滚 SQL(本脚本只加不减,回滚即逐条 DROP,不会丢任何数据):
- -- ALTER TABLE ic_bom_child DROP INDEX idx_ic_bom_child_tenant_bom;
- -- ALTER TABLE ic_bom_child DROP INDEX idx_ic_bom_child_tenant_item;
- -- ALTER TABLE ic_bom_child DROP PRIMARY KEY;
- -- ALTER TABLE ItemMaster DROP INDEX idx_ItemMaster_tenant_item;
- -- ALTER TABLE ic_bom DROP INDEX idx_ic_bom_tenant_item;
- -- ALTER TABLE ic_bom DROP INDEX idx_ic_bom_tenant_bomnum;
- -- ALTER TABLE InvMaster DROP INDEX idx_InvMaster_tenant_item;
- -- ALTER TABLE PurOrdDetail DROP INDEX idx_PurOrdDetail_item_ord;
- -- ALTER TABLE ic_item_stockoccupy DROP INDEX idx_ic_item_stockoccupy_tenant_bang;
- -- ALTER TABLE b_bom_child_examine DROP INDEX idx_b_bom_child_examine_examine;
- -- ALTER TABLE b_examine_result DROP INDEX idx_b_examine_result_tenant_entry;
- -- ALTER TABLE b_examine_result DROP INDEX idx_b_examine_result_tenant_morder;
- -- 回滚后还需把 sys_db_migration_log 中 version='1.0.321' 的行删除,脚本才会重跑。
- -- ============================================================================
|