yii模型查询性能监控需自动发现慢查询并告警,核心是实时接入耗时指标:启用db组件的enableprofiling和enableparamlogging,配置日志target捕获sql,监听event_after_execute事件判断超500ms写警告日志,并集成sentry实现主动告警。

Yii模型查询性能监控要能自动发现慢查询并触发告警,不能等用户投诉才去翻日志——关键在于把数据库查询耗时指标实时接入监控链路,同时让慢查询在调试工具栏里一眼可见、在日志里可追溯、在告警系统里可拦截。
启用并验证 Yii 的 SQL 日志与耗时统计
第一步:在 config/web.php 或 config/main.php 的 components 中,确保 log 组件已配置 DbTarget 或 FileTarget,且 categories 包含 'yii\db\Command::query' 和 'yii\db\Command::execute'。
第二步:在 db 组件中开启 enableProfiling 和 enableParamLogging:
'db' => [ 'class' => 'yii\db\Connection', 'enableProfiling' => true, 'enableParamLogging' => true, // 记录绑定参数,便于复现 ... ]
第三步:访问任意页面后,打开调试工具栏 → 点击 “Database” 标签页 → 查看每条 SQL 后面的耗时(单位:ms)。【若此处无耗时数字,说明 enableProfiling 未生效或被 config 覆盖】
自定义慢查询日志拦截器
方法一:重写 yii\db\Connection::createCommand(),在执行前打点,执行后判断耗时并写日志
方法二(推荐):监听 yii\db\Command::EVENT_AFTER_EXECUTE 事件,在 common/config/main.php 中添加:
'on yii\db\Command::EVENT_AFTER_EXECUTE' => function ($event) { $duration = $event->sender->getExecutionTime() * 1000; if ($duration > 500) { // 超500ms记为慢查询 Yii::warning("Slow SQL ({$duration}ms): " . $event->sender->getRawSql(), 'slow-query'); } };
这一步必须放在 components 外层,否则事件监听器不注册;【注意:不要在控制器里动态绑定该事件,否则仅对当前请求生效】
对接外部告警系统(以 Sentry 为例)
① 安装 Sentry SDK:composer require sentry/sentry
② 在 config/main.php 的 bootstrap 数组中加入 'sentry',并注册组件:
'sentry' => [ 'class' => 'sentry\sdk\SentryComponent', 'dsn' => 'https://xxx@o123.ingest.sentry.io/456', ],
③ 修改上一步的慢查询监听逻辑,加入 Sentry 上报:
if ($duration > 500) { Yii::warning(...); \Sentry\captureMessage("Slow Query {$duration}ms: " . mb_strimwidth($event->sender->getRawSql(), 0, 120)); }
④ 部署后,只要某次查询超时,Sentry 控制台立即出现带 SQL 片段、堆栈、请求 URL 的告警事件,点击即可定位到具体 Action 和行号。
这一步做完,慢查询就从“被动排查”变成“主动拦截”。











