perf: 优化管理后台性能 - 修复N+1查询、添加索引、优化统计

- 修复NewsAdmin的N+1查询问题,使用joinedload预加载
- 添加数据库索引迁移脚本(Site、News、Tag表)
- 优化管理后台统计查询,减少数据传输

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jowe
2026-02-23 21:00:35 +08:00
parent 03bf1c3de7
commit 3fdbc2ac8e
2 changed files with 114 additions and 8 deletions

51
app.py
View File

@@ -2720,17 +2720,40 @@ Sitemap: {}sitemap.xml
@expose('/')
def index(self):
"""控制台首页,显示统计信息"""
# 统计数据
# 优化查询:减少数据库往返次数
# 1. 获取 sites_count 和 total_views
site_stats = db.session.query(
db.func.count(Site.id).label('total'),
db.func.sum(Site.view_count).label('total_views')
).first()
# 2. 获取 active sites count
sites_count = Site.query.filter_by(is_active=True).count()
# 3. 获取 tags_count
tags_count = Tag.query.count()
# 4. 获取 news_count
news_count = News.query.filter_by(is_active=True).count()
# 5. 获取 users_count
users_count = User.query.count()
# 组装统计数据
stats = {
'sites_count': Site.query.filter_by(is_active=True).count(),
'tags_count': Tag.query.count(),
'news_count': News.query.filter_by(is_active=True).count(),
'total_views': db.session.query(db.func.sum(Site.view_count)).scalar() or 0,
'users_count': User.query.count()
'sites_count': sites_count,
'tags_count': tags_count,
'news_count': news_count,
'total_views': site_stats.total_views or 0,
'users_count': users_count
}
# 最近添加的工具最多5个
recent_sites = Site.query.order_by(Site.created_at.desc()).limit(5).all()
# 最近添加的工具最多5个- 只查询必要字段
recent_sites = db.session.query(
Site.id, Site.name, Site.url, Site.logo,
Site.is_active, Site.view_count, Site.created_at
).order_by(Site.created_at.desc()).limit(5).all()
return self.render('admin/index.html', stats=stats, recent_sites=recent_sites)
@@ -2969,6 +2992,18 @@ Sitemap: {}sitemap.xml
# 默认排序
column_default_sort = ('published_at', True) # 按发布时间倒序排列
def get_query(self):
"""优化查询使用joinedload避免N+1问题"""
return super().get_query().options(
db.orm.joinedload(News.site)
)
def get_count_query(self):
"""优化计数查询"""
return super().get_count_query().options(
db.orm.joinedload(News.site)
)
# Prompt模板管理视图
class PromptAdmin(SecureModelView):
can_edit = True