Files
biz-api-cloud-zax/db/20260914_add_wallet_active_card_pool_index.sql
T
dzc 3b9ad6580a feat:大量导入用户创建钱包死锁问题
feat:自动核销
feat:订单页面修改、订单地图
2026-09-14 18:34:16 +08:00

41 lines
2.3 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- 钱包开卡表抢卡死锁治理索引。
--
-- 适用接口:GET /wallet-manage/create-wallet(用户批量导入触发的并发创建钱包+自动绑卡)等 createAndActiveCard 路径。
-- 背景:抢卡 SQL 按 merchant_id = ? + user_id IS NULL 过滤并 ORDER BY card_sort LIMIT 1 FOR UPDATE;
-- 原表仅有主键和 (user_id) 单列索引,锁定读需经索引扫描全部空闲卡再 filesort,
-- 实际锁范围覆盖全表空闲卡直到事务提交,并与自动补卡的批量 INSERT 插入意向锁互相等待,
-- 大批量用户导入并发建钱包时产生集中死锁。
-- 索引效果:范围收敛为单商户空闲卡区间且天然按 card_sort 有序,FOR UPDATE 免排序、取满 LIMIT 1 即停止,
-- 每笔事务仅锁定队首一张卡;同时加速绑卡前的空闲卡余量 COUNT。
-- 执行影响:仅新增普通索引,不修改字段、约束和历史数据;建索引期间消耗 IO,建议业务低峰期执行。
-- 执行前建议:先备份数据库,并用文末查询核对生产库 wallet_active 实际已有索引。
SET @index_ddl = IF(
EXISTS (
SELECT 1
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'wallet_active'
AND index_name = 'idx_wallet_active_merchant_user_sort'
),
'SELECT ''idx_wallet_active_merchant_user_sort already exists'' AS message',
'ALTER TABLE `wallet_active` ADD INDEX `idx_wallet_active_merchant_user_sort` (`merchant_id`, `user_id`, `card_sort`)'
);
PREPARE index_stmt FROM @index_ddl;
EXECUTE index_stmt;
DEALLOCATE PREPARE index_stmt;
-- 执行后核对新增索引;确认与既有 idx_dept_id(user_id) 无同前缀冗余。
SELECT table_name, index_name, seq_in_index, column_name
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'wallet_active'
ORDER BY table_name, index_name, seq_in_index;
-- 建议执行后更新统计信息,并用真实商户参数验证抢卡 SQL 计划不再 filesort:
-- ANALYZE TABLE wallet_active;
-- EXPLAIN SELECT id, ... FROM wallet_active
-- WHERE del_flag = '0' AND user_id IS NULL AND wallet_id IS NULL
-- AND merchant_id = ? AND is_active_hardware = '0' AND tenant_id = ?
-- ORDER BY card_sort ASC LIMIT 1 FOR UPDATE;