優化 adminUserController.cs 的子查詢性能

問題:
Line 93 將所有會員的 admin_num 載入內存(ToList)
- 如果有 10,000 個會員,載入 10,000 個 int (40KB)

優化:
改為使用 IQueryable 子查詢,在數據庫層面執行
- var usedAdminNums = _db.members.Select(b => b.admin_num);  // 不 ToList()
- 生成 SQL: WHERE num NOT IN (SELECT admin_num FROM members)

效果:
✓ 減少內存占用:40KB → 0
✓ 減少查詢次數:2 次 → 1 次
✓ SQL 優化器可以更好地優化查詢計劃

對比原始代碼:
- 原始(嵌套 AsEnumerable):N+1 查詢問題,執行 51 次
- ToList 版本:載入 40KB,執行 2 次
- 當前版本:不載入內存,執行 1 次(最佳)
This commit is contained in:
2025-11-12 17:27:35 +08:00
parent bc1f1422e9
commit eff3ad778b

View File

@@ -90,14 +90,15 @@ public class adminUserController : ApiController
if(q.removeExist.HasValue && q.removeExist.Value)
{
var existingAdminNums = _db.members.Select(b => b.admin_num).ToList();
// 優化:使用子查詢在數據庫層面執行,避免載入所有會員的 admin_num
var usedAdminNums = _db.members.Select(b => b.admin_num);
if (q.num.HasValue && q.num.Value > 0)
{
qry = qry.Where(o => !existingAdminNums.Contains(o.num) || o.num == q.num.Value);
qry = qry.Where(o => !usedAdminNums.Contains(o.num) || o.num == q.num.Value);
}
else
{
qry = qry.Where(o => !existingAdminNums.Contains(o.num));
qry = qry.Where(o => !usedAdminNums.Contains(o.num));
}
}