1.0.321.sql 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. -- 1.0.321.sql S2 排程性能 L1:齐套检查/BOM 展开热点路径补齐二级索引。
  2. -- 背景:EXPLAIN ANALYZE 实测 ic_bom_child 子件查询扫 59,799+22,108 行、服务端 103ms;
  3. -- InvMaster 库存查询扫 18,368 行、17.9ms。二者均为全表扫描(无可用索引)。
  4. -- 本脚本只建【非唯一】二级索引 + 一个主键,不改字段类型/可空性,不增删改任何业务数据,
  5. -- 不删除任何现有索引。因此不存在数据冲突导致失败的可能,无需前置去重。
  6. -- 索引列依据见 doc/plan/S2排程性能-L1索引体系执行任务书.md §2.4(逐条对应实际查询条件)。
  7. -- ============================================================================
  8. -- ========== 〇、通用幂等宏说明 ==========
  9. -- 每个索引统一走:查 information_schema.STATISTICS 判是否已存在 -> 不存在才 ADD。
  10. -- 重复执行本脚本不会报错,也不会重复创建。
  11. -- ========== 一、ic_bom_child(59,799 行,当前零索引含主键) ==========
  12. -- 1.1 主键。已实证 Id 全部唯一且非空(59799/59799,null=0);
  13. -- 且全仓库无任何应用侧 INSERT 写该表(仅 MaterialRequirementCalculator 的 SELECT),
  14. -- 不会因新主键产生重复键失败。
  15. SET @has_pk := (SELECT COUNT(*) FROM information_schema.STATISTICS
  16. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom_child' AND INDEX_NAME = 'PRIMARY');
  17. SET @sql := IF(@has_pk = 0,
  18. 'ALTER TABLE ic_bom_child ADD PRIMARY KEY (Id)', 'DO 0');
  19. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  20. -- 1.2 主查询路径:WHERE bom_id=? AND tenant_id=? AND IsDeleted=0
  21. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  22. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom_child'
  23. AND INDEX_NAME = 'idx_ic_bom_child_tenant_bom');
  24. SET @sql := IF(@has_ix = 0,
  25. 'ALTER TABLE ic_bom_child ADD INDEX idx_ic_bom_child_tenant_bom (tenant_id, bom_id, IsDeleted)', 'DO 0');
  26. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  27. -- 1.3 反查父阶 / 按物料查用量
  28. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  29. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom_child'
  30. AND INDEX_NAME = 'idx_ic_bom_child_tenant_item');
  31. SET @sql := IF(@has_ix = 0,
  32. 'ALTER TABLE ic_bom_child ADD INDEX idx_ic_bom_child_tenant_item (tenant_id, item_number)', 'DO 0');
  33. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  34. -- ========== 二、ItemMaster(22,108 行) ==========
  35. -- 现有 uk_ItemMaster_factory_item (tenant_id, factory_ref_id, ItemNum) 因中间缺 factory_ref_id
  36. -- 无法服务 BOM 子件关联,补 (tenant_id, ItemNum)。不动现有唯一索引。
  37. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  38. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ItemMaster'
  39. AND INDEX_NAME = 'idx_ItemMaster_tenant_item');
  40. SET @sql := IF(@has_ix = 0,
  41. 'ALTER TABLE ItemMaster ADD INDEX idx_ItemMaster_tenant_item (tenant_id, ItemNum)', 'DO 0');
  42. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  43. -- ========== 三、ic_bom(5,431 行) ==========
  44. -- 3.1 ResolveBomIdByItemAsync:WHERE tenant_id=? AND IsDeleted=0 AND item_number=?
  45. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  46. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom'
  47. AND INDEX_NAME = 'idx_ic_bom_tenant_item');
  48. SET @sql := IF(@has_ix = 0,
  49. 'ALTER TABLE ic_bom ADD INDEX idx_ic_bom_tenant_item (tenant_id, item_number, IsDeleted)', 'DO 0');
  50. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  51. -- 3.2 ResolveBomIdAsync 的 bom_number 分支
  52. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  53. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_bom'
  54. AND INDEX_NAME = 'idx_ic_bom_tenant_bomnum');
  55. SET @sql := IF(@has_ix = 0,
  56. 'ALTER TABLE ic_bom ADD INDEX idx_ic_bom_tenant_bomnum (tenant_id, bom_number)', 'DO 0');
  57. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  58. -- ========== 四、InvMaster(18,368 行) ==========
  59. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  60. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'InvMaster'
  61. AND INDEX_NAME = 'idx_InvMaster_tenant_item');
  62. SET @sql := IF(@has_ix = 0,
  63. 'ALTER TABLE InvMaster ADD INDEX idx_InvMaster_tenant_item (tenant_id, ItemNum)', 'DO 0');
  64. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  65. -- ========== 五、PurOrdDetail(95 行,为将来增长预留) ==========
  66. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  67. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'PurOrdDetail'
  68. AND INDEX_NAME = 'idx_PurOrdDetail_item_ord');
  69. SET @sql := IF(@has_ix = 0,
  70. 'ALTER TABLE PurOrdDetail ADD INDEX idx_PurOrdDetail_item_ord (ItemNum, PurOrdRecID)', 'DO 0');
  71. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  72. -- ========== 六、ic_item_stockoccupy(497 行;排程起始 DELETE + 占用汇总) ==========
  73. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  74. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ic_item_stockoccupy'
  75. AND INDEX_NAME = 'idx_ic_item_stockoccupy_tenant_bang');
  76. SET @sql := IF(@has_ix = 0,
  77. 'ALTER TABLE ic_item_stockoccupy ADD INDEX idx_ic_item_stockoccupy_tenant_bang (tenant_id, bang_id, IsDeleted)', 'DO 0');
  78. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  79. -- ========== 七、b_bom_child_examine(8,679 行,齐套结果明细) ==========
  80. -- examine_id 必须最左:ResourceCheckResultWriter 的 UPDATE 只带 examine_id、不带 tenant_id。
  81. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  82. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'b_bom_child_examine'
  83. AND INDEX_NAME = 'idx_b_bom_child_examine_examine');
  84. SET @sql := IF(@has_ix = 0,
  85. 'ALTER TABLE b_bom_child_examine ADD INDEX idx_b_bom_child_examine_examine (examine_id, tenant_id, is_use)', 'DO 0');
  86. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  87. -- ========== 八、b_examine_result(279 行,齐套结果头) ==========
  88. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  89. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'b_examine_result'
  90. AND INDEX_NAME = 'idx_b_examine_result_tenant_entry');
  91. SET @sql := IF(@has_ix = 0,
  92. 'ALTER TABLE b_examine_result ADD INDEX idx_b_examine_result_tenant_entry (tenant_id, sentry_id, IsDeleted)', 'DO 0');
  93. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  94. SET @has_ix := (SELECT COUNT(DISTINCT INDEX_NAME) FROM information_schema.STATISTICS
  95. WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'b_examine_result'
  96. AND INDEX_NAME = 'idx_b_examine_result_tenant_morder');
  97. SET @sql := IF(@has_ix = 0,
  98. 'ALTER TABLE b_examine_result ADD INDEX idx_b_examine_result_tenant_morder (tenant_id, morder_no)', 'DO 0');
  99. PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
  100. -- ========== 九、刷新统计信息,让优化器立刻用上新索引 ==========
  101. ANALYZE TABLE ic_bom_child;
  102. ANALYZE TABLE ItemMaster;
  103. ANALYZE TABLE ic_bom;
  104. ANALYZE TABLE InvMaster;
  105. ANALYZE TABLE PurOrdDetail;
  106. ANALYZE TABLE ic_item_stockoccupy;
  107. ANALYZE TABLE b_bom_child_examine;
  108. ANALYZE TABLE b_examine_result;
  109. -- ============================================================================
  110. -- 回滚 SQL(本脚本只加不减,回滚即逐条 DROP,不会丢任何数据):
  111. -- ALTER TABLE ic_bom_child DROP INDEX idx_ic_bom_child_tenant_bom;
  112. -- ALTER TABLE ic_bom_child DROP INDEX idx_ic_bom_child_tenant_item;
  113. -- ALTER TABLE ic_bom_child DROP PRIMARY KEY;
  114. -- ALTER TABLE ItemMaster DROP INDEX idx_ItemMaster_tenant_item;
  115. -- ALTER TABLE ic_bom DROP INDEX idx_ic_bom_tenant_item;
  116. -- ALTER TABLE ic_bom DROP INDEX idx_ic_bom_tenant_bomnum;
  117. -- ALTER TABLE InvMaster DROP INDEX idx_InvMaster_tenant_item;
  118. -- ALTER TABLE PurOrdDetail DROP INDEX idx_PurOrdDetail_item_ord;
  119. -- ALTER TABLE ic_item_stockoccupy DROP INDEX idx_ic_item_stockoccupy_tenant_bang;
  120. -- ALTER TABLE b_bom_child_examine DROP INDEX idx_b_bom_child_examine_examine;
  121. -- ALTER TABLE b_examine_result DROP INDEX idx_b_examine_result_tenant_entry;
  122. -- ALTER TABLE b_examine_result DROP INDEX idx_b_examine_result_tenant_morder;
  123. -- 回滚后还需把 sys_db_migration_log 中 version='1.0.321' 的行删除,脚本才会重跑。
  124. -- ============================================================================