34 lines
2.2 KiB
SQL
34 lines
2.2 KiB
SQL
-- 20261009 钱包账户管理分页索引(可重复执行)
|
||
--
|
||
-- 背景:/wallet/wallet-manage/page-join 分页查询(scopePage:tenant_id+del_flag 等值过滤,
|
||
-- 默认 order by create_time desc, user_id desc, wallet_type_id asc, id desc)在
|
||
-- wallet_manage 上没有任何以 tenant_id 为前导的索引(现有:idx_dept_id(user_id)、
|
||
-- idx_wallet_manage_card_tenant_del(card_number,tenant_id,del_flag)、
|
||
-- idx_wallet_manage_id_tenant(id,tenant_id)、idx_wallet_manage_wallet_type_dept(wallet_type_id,dept_id)),
|
||
-- EXPLAIN 实测 type=ALL 全表扫描 + Using filesort;线上 21.9 万行单次翻页约 28 秒(含 COUNT 复扫)。
|
||
-- 方案:新增与 ORDER BY 列方向完全一致的分页索引。MySQL 8.0 起支持降序索引,
|
||
-- 等值前缀 (tenant_id, del_flag) 之后 (create_time DESC, user_id DESC, wallet_type_id ASC, id DESC)
|
||
-- 与查询排序逐列同向,优化器可直接沿索引取前 10 行,filesort 消失;COUNT 走同一索引前缀区间。
|
||
-- 执行:Online DDL(INPLACE + LOCK=NONE,不锁表);线上 21.9 万行预计 5~20 秒,建议低峰执行。
|
||
-- 可重复执行(information_schema 判幂等,已存在则跳过)。
|
||
-- 回滚:文末 DROP INDEX。
|
||
|
||
USE pjcloudx_wallet;
|
||
SET @ddl = IF(
|
||
(SELECT COUNT(*) FROM information_schema.statistics
|
||
WHERE table_schema = 'pjcloudx_wallet' AND table_name = 'wallet_manage'
|
||
AND index_name = 'idx_wallet_manage_page_list') = 0,
|
||
'ALTER TABLE wallet_manage ADD INDEX idx_wallet_manage_page_list (tenant_id, del_flag, create_time DESC, user_id DESC, wallet_type_id ASC, id DESC), ALGORITHM=INPLACE, LOCK=NONE',
|
||
'SELECT ''skip: idx_wallet_manage_page_list 已存在'' AS msg');
|
||
PREPARE stmt FROM @ddl;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
-- ============ 执行后验证(期望 key=idx_wallet_manage_page_list,type=ref,Extra 无 Using filesort) ============
|
||
-- EXPLAIN SELECT id FROM pjcloudx_wallet.wallet_manage
|
||
-- WHERE tenant_id = 1 AND del_flag = '0'
|
||
-- ORDER BY create_time DESC, user_id DESC, wallet_type_id ASC, id DESC LIMIT 10;
|
||
|
||
-- ============ 回滚(如需) ============
|
||
-- ALTER TABLE pjcloudx_wallet.wallet_manage DROP INDEX idx_wallet_manage_page_list;
|