🟢 一、库存独立维护表(库存快照)

当前使用的 SQL:

SELECT d.mID, SUM(d.iQty)-SUM(d.oQty) AS mstock
FROM IOD d INNER JOIN IO m ON d.RecordID = m.RecordID
WHERE ISNULL(m.ReportStatus,0) = 2
GROUP BY d.mID

这种方式实时计算库存,涉及频繁的汇总计算,在大数据量时尤其慢。

建议新增一张库存余额表

例如:

CREATE TABLE InventoryBalance (
    mID INT PRIMARY KEY,     -- 商品ID
    CurrentStock INT NOT NULL -- 当前库存数量
);

优点:

  • 每次只需单行读取,大幅提升速度。
  • 可以更好地应用行级锁,减轻锁竞争。

缺点:

  • 需要额外维护库存余额一致性(通过触发器或应用逻辑更新)。

🟢 二、定时库存汇总(离线库存快照)

一种常见的折中方法,是每隔一段时间汇总一次库存,而非每次读取实时汇总:

  • 每小时或每天凌晨更新一次库存表,库存更新完毕后前台直接读取此库存快照。
  • 每次交易时仅更新快照的增量变化,而不是整体汇总。

优点:

  • 大幅度减少实时汇总的开销,查询速度快。

缺点:

  • 会存在一定的延迟(例如:库存每小时更新一次)。
  • 需要管理增量库存的变化。

🟢 三、库存变动事件化(异步库存更新)

借助消息队列或日志表异步更新库存:

  • 每次库存变化插入一个消息或记录一条日志。
  • 后台定时消费消息,批量更新库存余额。

例如流程:

用户出库 → 写入库存变动消息 → 后台定期消费队列更新库存余额表

优点:

  • 库存读取完全独立且快速,前端读取无延迟。
  • 减少事务阻塞和锁竞争,数据库压力降低。

缺点:

  • 库存短期内可能存在不一致(秒级延迟),需考虑对业务影响。
  • 系统架构复杂性提高,需维护消息队列。

🟢 四、分布式缓存库存(Redis等)

利用缓存(如Redis)维护库存余额:

  • 库存读取直接从缓存快速响应。
  • 库存变更同时更新缓存和数据库(使用双写策略或数据库写成功后更新缓存)。

示例(伪代码):

//读取库存
stock, err := redis.Get("stock:商品ID")

//更新库存
redis.DecrBy("stock:商品ID", qty)
db.Exec("UPDATE Inventory SET CurrentStock=CurrentStock-@qty WHERE mID=@mID")

优点:

  • 极快的读取速度,降低数据库压力。
  • 通过Redis原子操作,轻松实现并发安全扣减。

缺点:

  • 数据库和缓存需保持同步,容易发生不一致问题(需额外逻辑保障)。

🟢 五、乐观锁 + 重试机制(最推荐)

使用库存余额表配合乐观锁和重试机制:

--扣减库存示例
UPDATE InventoryBalance
SET CurrentStock = CurrentStock - @qty
WHERE mID = @mID AND CurrentStock >= @qty
  • 如果扣减失败(库存不足或冲突),应用程序可以快速重试几次或提示用户。

优点:

  • 事务和锁粒度最小,对数据库压力最小。
  • 并发能力高、性能好,重试机制可保障可靠性。

缺点:

  • 需要应用程序实现重试逻辑,增加少许复杂性。

🟢 综合推荐方案(最佳实践)

综合考虑 WMS 系统的特点,推荐:

步骤 推荐方案 原因
1 维护专门的库存余额表 避免频繁聚合计算
2 使用乐观锁 (WHERE条件校验库存) 高性能、低锁粒度,数据库压力小
3 前端可使用缓存快速读取库存 读取压力大幅降低,适合大量频繁读取场景
4 后端使用异步队列或批量任务更新库存 分流峰值压力,异步更新减少数据库阻塞

例如实际应用时的流程:

  • 实时扣减库存(出库/审核时):

    • 使用乐观锁快速扣减,失败则重试或提示不足。
  • 库存读取

    • 优先读取缓存,未命中则从库存余额表读取后更新缓存。
  • 后台定时任务

    • 定时(每分钟/小时)批量核对库存余额,纠正可能的不一致。

🚩 注意事项

  • 在高并发 WMS 环境,完美一致性和极高性能不可能同时满足。推荐选择上述折中方案,保持库存一致性在可控范围内,并定期校正。
  • 避免每次实时聚合计算库存,这会带来严重性能问题。
  • 应用和数据库配合使用,乐观锁 + 缓存方案最能满足性能和并发需求。

以上策略可有效解决库存高频读取与数据库性能瓶颈的矛盾,提升整体响应速度,满足WMS系统的业务要求。