# 2026-06-24 更新日志
## SQL 性能优化(*****/route 后台路由)
### SubTask 4.1: 修复附件列表全表 count bug
- 文件:`*****/route/attach.php`、`model/attach.func.php`
- 问题:有筛选条件时反而执行 `db_count('attach')` 无 WHERE 全表 count
- 修复:新增 `attach_*****_count($filter)` 函数,构建带筛选条件的 COUNT SQL,替代无条件全表 count
### SubTask 4.2: 优化积分日志今日收入/支出统计
- 文件:`*****/route/log.php`
- 问题:查询今日最多 10000 条记录后在 PHP 中 foreach 求和
- 修复:改用 SQL SUM 聚合查询,一次查询替代全表扫描 + PHP 求和
### SubTask 4.3: 优化后台首页 30 天趋势图
- 文件:`*****/route/index.php`
- 问题:for 循环 30 天,每天 4 次 db_count(),共 120 次 count 查询
- 修复:改用 GROUP BY FLOOR((create_date - start) / 86400) 聚合查询,4 次查询替代 120 次
### SubTask 4.4: 优化附件列表 N+1 查询
- 文件:`*****/route/attach.php`
- 问题:foreach 循环内逐条调用 `user_read_cache()` 和 `db_find_one('post')`
- 修复:改用 `db_find()` 批量查询用户和 post,以 uid/pid 为键构建映射
### SubTask 4.5: 优化版块列表双倍写入
- 文件:`*****/route/forum.php`
- 问题:每条版块更新后额外调用 `forum_update()` 更新 icon(双倍写入)
- 修复:合并 icon 字段到主更新数组,一次更新完成
### SubTask 4.6: 优化版块权限批量替换
- 文件:`*****/route/forum.php`
- 问题:foreach 循环内逐条调用 `forum_access_replace()`(每条先 SELECT 再 INSERT/UPDATE)
- 修复:改用批量 `INSERT ... ON DUPLICATE KEY UPDATE`,一次 SQL 完成所有权限替换
### SubTask 4.7: 优化版块管理 N+1 用户查询
- 文件:`*****/route/forum.php`
- 问题:getname 动作及 `user_names_to_ids()`/`user_ids_to_names()` 函数 foreach 内逐条查询用户
- 修复:改用 `db_find()` 批量查询用户,以 uid/username 为键构建映射
### SubTask 4.8: 优化主题批量操作
- 文件:`*****/route/thread.php`
- 问题:队列操作和批量操作中 foreach 循环内逐条 `thread_update()`/`thread_read()`
- 修复:
- 简单字段更新(close/open/top/announcement)改用批量 `db_update()`
- digest 操作改用 `thread_find_by_tids()` 批量读取后再逐条处理
- delete 和 move 操作保持循环(涉及级联删除和 forum 计数更新)
## SQL 性能优化(model 层)
### SubTask 1.1-1.4: 动态排序白名单验证(安全)
- 文件:`model/thread.func.php`、`model/forum.func.php`、`model/attach.func.php`、`model/modlog.func.php`
- 问题:$order/$orderby 参数直接作为 ORDER BY 字段,未做白名单验证(SQL 注入风险)
- 修复:在函数开头增加白名单验证,非法字段回退到默认排序,不抛异常
### SubTask 1.5: forum_delete 分批处理
- 文件:`model/forum.func.php`
- 问题:forum_delete() 查询最多 100 万条数据无分页
- 修复:改为分批处理(每次 1000 条),避免内存溢出
### SubTask 1.6: session 全表扫描优化
- 文件:`model/session.func.php`
- 问题:online_find_cache() 无 WHERE 无 LIMIT 返回全部 session
- 修复:增加 WHERE last_date 条件和 LIMIT 1000 限制
### SubTask 1.7: attach 孤儿附件分页
- 文件:`model/attach.func.php`
- 问题:attach_*****_orphan_ids() LEFT JOIN 无 LIMIT
- 修复:增加分页参数支持(默认每页 1000)
### SubTask 1.8-1.14: model 层 N+1 查询消除
- 文件:`model/post.func.php`、`model/user.func.php`、`model/forum.func.php`、`model/attach.func.php`、`model/forum_access.func.php`
- 修复:
- post_delete_by_tid 改为批量 db_delete
- post_format 增加静态缓存减少重复查询
- post_list_access_filter 批量 thread_find_by_tids
- user_delete 改为分批处理
- forum_filter_moduid 批量 user_find_by_uids
- attach 多处改为批量操作
- forum_access_delete_by_fid 改为 db_delete(fid IN)
### SubTask 1.15-1.19: model 层 N+1 查询消除(续)
- 文件:`model/user_follow.func.php`、`model/thread_favorite.func.php`、`model/forum_follow.func.php`、`model/mythread.func.php`、`model/notify.func.php`
- 修复:
- user_follow_delete_by_uid 改为批量 UPDATE WHERE uid IN
- thread_favorite_delete_by_tid 改为批量 UPDATE WHERE uid IN
- forum_follow_check_batch 改为 db_find IN 查询
- mythread_find_by_uid 改为 thread_find_by_tids 批量查询
- notify_format 增加可选预加载参数,notify_find_by_uid 等 4 个批量函数预加载 user/thread/post
## SQL 性能优化(lib 服务层)
### SubTask 2.1: 积分日志分组查询优化
- 文件:`lib/CreditsService.php`
- 问题:logGrouped() 一次取 10 万条日志在 PHP 内分组
- 修复:改为 SQL GROUP BY create_date, reason + 分页查询,使用 GROUP_CONCAT 聚合字段
### SubTask 2.2-2.5: 审核服务 N+1 查询消除
- 文件:`lib/security/AuditService.php`
- 修复:
- get_pending_list 批量查询 user/forum/thread
- approve 批量查询 notify 去重 + 批量插入通知
- approve @提及批量 user_find
- get_audit_logs 批量 user_find
- 新增 batch_read_users 私有方法实现带缓存的批量用户查询
### SubTask 2.6-2.7: 举报服务 N+1 查询消除
- 文件:`lib/security/ReportService.php`
- 修复:
- get_list 批量查询 user/thread/post
- notify_*****s 改为批量 INSERT SQL 一次性插入所有***通知
### SubTask 2.8: 权限服务批量 upsert
- 文件:`lib/PermissionService.php`
- 问题:updatePermissions 循环内逐条 db_find_one + db_update/db_insert
- 修复:改为 INSERT ... ON DUPLICATE KEY UPDATE 批量 upsert,从 2N 次查询降为 1 次
## SQL 性能优化(route 前台路由)
### SubTask 3.1: 搜索 FULLTEXT 无分页修复
- 文件:`route/search.php`
- 问题:FULLTEXT 搜索 3 条 SQL 无 LIMIT 限制
- 修复:增加 LIMIT 100 限制
### SubTask 3.2: 发帖通知无分页修复
- 文件:`route/thread.php`
- 问题:forum_follow_find_by_fid 无分页取所有关注用户
- 修复:array_slice 限制最多 1000 人
### SubTask 3.3: 版主批量操作 N+1 消除
- 文件:`route/mod.php`
- 修复:
- close/move/audit/announcement 改为批量 db_update
- top/delete/digest 保持循环(涉及级联操作)
- audit 批量 thread_find_by_tids 替代逐条 thread_read
### SubTask 3.4-3.5: 通知/收藏列表 N+1 消除
- 文件:`route/my.php`
- 修复:
- 收藏列表批量 thread_find_by_tids
- 通知列表批量查询 thread/post/user,forum 从全局 $forumlist 缓存取
### SubTask 3.6: 搜索结果 N+1 消除
- 文件:`route/search.php`
- 修复:搜索结果批量查询主帖(db_find IN)
### SubTask 3.7: 发帖通知 N+1 消除
- 文件:`route/thread.php`
- 修复:批量查询已存在通知 + 批量创建新通知
### SubTask 3.8: 用户主页收藏/点赞列表 N+1 消除
- 文件:`route/user.php`
- 修复:5 处收藏/点赞列表改为批量 thread_find_by_tids
## 通用说明
- 所有修改保持函数签名兼容(无 BREAKING CHANGE)
- 批量查询使用 IN 语法时对空数组做防护
- 白名单验证不抛异常,仅回退默认值
- 已清理 tmp/ 缓存