Yii性能瓶颈主要在数据库和缓存配置:1.启用Schema缓存需同时设enableSchemaCache和schemaCacheDuration;2.with()预加载应配合asArray()减少内存;3.Redis缓存须正确配置类名和keyPrefix;4.PageCache必须指定only和duration。

Yii 应用跑得慢,八成卡在数据库和缓存配置上,而不是框架本身。 它默认够快,但一旦没关调试、没配缓存、没处理 N+1 查询,性能会断崖式下跌。下面直奔实操点,不讲虚的。
启用 Schema 缓存却没设 duration 导致 DB 连接池耗尽
开启 enableSchemaCache 但漏掉 schemaCacheDuration,是高频踩坑点。Yii 会把 schema 缓存时间设为 0,每次请求都尝试刷新元数据,反复查 information_schema 表,主库连接数飙升,甚至拖垮整个 MySQL。
- 必须在
config/db.php的db组件中同时配置这两项:'enableSchemaCache' => true和'schemaCacheDuration' => 3600 -
schemaCache默认用的是cache组件,所以要先确认cache已正确启用(比如 Redis 或 APCu),否则缓存自动失效 - 开发环境可设短一点(如 60),生产环境建议 3600 或更长;表结构变更后,手动清空缓存或等它过期即可
with() 预加载没加 asArray(),Active Record 对象构造吃光内存
列表页调用 Post::find()->with('author', 'category')->all() 看似解决了 N+1,但如果返回几千条记录,每个 Post、Author、Category 都实例化为完整 AR 对象,PHP 内存占用会翻几倍,GC 压力大,响应变慢。
- 纯数据读取场景(如 API 接口、导出、后台统计),一律补上
->asArray():Post::find()->with('author')->asArray()->all() -
asArray()后关联字段变成嵌套数组(如['author' => ['id' => 1, 'name' => 'xxx']]),不能调用$post->author->name,但节省 60%+ 内存和构造开销 - 若需部分对象行为(如调用 getter),可只对主模型用
asArray(),关联仍走 AR —— 但得权衡,通常没必要
Redis 缓存组件配错类名或 keyPrefix 引发缓存击穿
很多项目照抄文档写 'class' => 'yii\redis\Cache',结果报错 Class 'yii\redis\Cache' not found,原因是没装 yiisoft/yii2-redis 扩展,或类名拼错(比如写成 yii\redis\cache 小写)。
- 先执行
composer require yiisoft/yii2-redis,再检查config/web.php中cache配置: - 类名必须是
'class' => 'yii\redis\Cache'(首字母大写,无下划线) -
keyPrefix必须设,尤其多应用共用一个 Redis 实例时,否则缓存键冲突,A 应用删了 B 应用的缓存 - 测试是否生效:在控制器里写
Yii::$app->cache->set('test_key', 'ok', 60),然后get('test_key')能取到值,再连 Redis 查KEYS myapp_*确认前缀存在
页面缓存没配 only 或 duration=0,导致缓存失效或永久不更新
PageCache 一配就“全站静态化”,这是误解。它只对指定 action 生效,且 duration 为 0 时等于禁用缓存(不是永不过期)。
- 必须显式声明
'only' => ['index', 'about'],否则该控制器所有 action 都被缓存,登录态、用户信息全错乱 -
'duration' => 0表示“不缓存”,想长期缓存就填大点数字,比如86400(一天) - 动态内容(如用户昵称、购物车数量)不能放
PageCache区域内,得用FragmentCache单独包住静态块 - 缓存生成后,修改视图文件不会自动失效,需靠
variations或手动flush,别指望它智能感知代码变更
真正卡顿的点往往藏在“以为配好了”的地方:Schema 缓存开着却没 duration,Redis 类名大小写不对,with() 后忘了 asArray(),PageCache 的 only 漏写。这些不是理论问题,是上线后立刻能监控到的 CPU 和内存拐点。优化不用大改架构,盯住这四类配置,效果立现。



















