PHPackages                             denny/laravel-sql-monitor - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. denny/laravel-sql-monitor

ActiveLibrary[Database &amp; ORM](/categories/database)

denny/laravel-sql-monitor
=========================

A comprehensive SQL query monitoring and analysis tool for Laravel development environments

v1.5.3(3mo ago)061MITPHPPHP ^8.1

Since Apr 14Pushed 3mo agoCompare

[ Source](https://github.com/Denny-Chu/laraval-sql-monitor)[ Packagist](https://packagist.org/packages/denny/laravel-sql-monitor)[ RSS](/packages/denny-laravel-sql-monitor/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (9)Versions (12)Used By (0)

Laravel SQL Monitor
===================

[](#laravel-sql-monitor)

[![Laravel](https://camo.githubusercontent.com/93554d1ac44e7880097a6bd117e99f90c33ddf03dcf0a37f3047fa50b8aaa4d2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31302532422d726564)](https://laravel.com)[![PHP](https://camo.githubusercontent.com/83dd395020c37276225039739320f6c8e7e99963ab21ee3d09282cb48dad2a60/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d626c7565)](https://php.net)[![License](https://camo.githubusercontent.com/5caa455d8debc46fb23abbadb45a733a937f3910a73fc875c2f7820468e1bb54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e)](#license)

一個全功能的 Laravel 擴展，提供**動態分析**（執行時監控）和**靜態分析**（AST 掃描）能力，幫助開發者在開發時期就發現和優化 SQL 查詢問題。

---

功能概覽
----

[](#功能概覽)

### 動態分析（執行後）

[](#動態分析執行後)

功能說明實時查詢監控捕獲每條 SQL 及執行時間複雜度評分自動計算查詢複雜度（0–100）N+1 檢測識別 N+1 查詢模式，代表查詢持久化到 DB重複查詢檢測找出完全相同的重複查詢，代表查詢持久化到 DBSlow Query 追蹤超過閾值即時寫入 DB，Log::warning 同步記錄雙層持久化問題查詢（DB 層）+ 正常查詢（Cache 層，TTL 60s）Dashboard Polling每 5 秒自動拉取，合併顯示 DB + Cache 查詢Call Stack 收集IDE 可點擊的調用棧### 靜態分析（執行前）

[](#靜態分析執行前)

透過 AST 解析 PHP 原始碼，**不需要執行查詢**即可偵測問題：

偵測項目issue code嚴重度SELECT \*`select-star`info無 WHERE 全表掃描`no-where`warning無 LIMIT 無界結果集`no-limit`warningWHERE 欄位缺少索引`missing-index`warning過量 JOIN（&gt;5）`excessive-joins`critical偏多 JOIN（&gt;3）`many-joins`warningJOIN 索引提示`join-index-hint`infoGROUP BY 索引提示`group-by-hint`infoLIMIT 無 ORDER BY`limit-without-order`infoUNION 使用提示`union-detected`infoEloquent N+1 風險`n1-risk`infoRaw SQL 偵測`raw-sql`info**複合索引建議**——---

安裝
--

[](#安裝)

```
composer require denny/laravel-sql-monitor
```

發布設定檔：

```
php artisan vendor:publish --tag=sql-monitor-config
```

啟用（`.env`）：

```
APP_ENV=local
SQL_MONITOR_ENABLED=true
```

> 套件只在 `APP_ENV=local` 或 `testing` 時啟動，生產環境不會載入。

---

靜態分析
----

[](#靜態分析)

### 基本用法

[](#基本用法)

```
# 掃描整個 app/ 目錄
php artisan sql-monitor:analyse

# 指定目錄
php artisan sql-monitor:analyse --path=app/Repositories

# 指定單一檔案
php artisan sql-monitor:analyse --path=app/Models/User.php

# 指定類別（完整命名空間或短名稱）
php artisan sql-monitor:analyse --class=UserRepository
php artisan sql-monitor:analyse --class="App\Repositories\UserRepository"
```

### 完整 CLI 選項

[](#完整-cli-選項)

選項預設說明`--path=`—分析指定目錄或檔案`--class=`—分析指定類別`--format=``table`輸出格式：`table` / `json` / `summary``--min-severity=``info`最低顯示嚴重度：`info` / `warning` / `critical``--sort=``file`排序：`file` / `cost` / `complexity` / `severity``--no-index-check`—跳過資料庫索引檢查（不需 DB 連線）`--no-index-recommend`—跳過複合索引建議計算### 輸出範例

[](#輸出範例)

```
=== app/Repositories/OrderRepository.php

  ▲ OrderRepository::findByUser()  行 24
    eloquent::where('user_id', '$userId')->where('status', '$status')->get
    表：order  | 複雜度：25/100 [OK]  | 成本：0.49 [LOW]
    ℹ  [select-star] 使用了 SELECT *
    ▲  [no-limit] 無 LIMIT 限制，可能回傳大量資料
    ▲  [missing-index] WHERE 欄位 `status` 在 `order` 表中無索引

=== 複合索引建議

  order（2 個建議，共 15 次查詢覆蓋）

    建議 1: (user_id, status)  使用次數：12
      → 等值欄位依選擇率排序：user_id(選擇率 0.920) → status(選擇率 0.005)
      ⚠  可 DROP 現有索引：idx_user（已被新索引 left-prefix 覆蓋）

    建議 2: (user_id, created_at)  使用次數：3
      → 等值欄位依選擇率排序：user_id(選擇率 0.920)
      → ORDER BY 欄位放尾端：created_at desc（可避免 filesort）

```

### JSON 輸出（適合 CI / diff）

[](#json-輸出適合-ci--diff)

```
php artisan sql-monitor:analyse --format=json | jq '.summary'
```

JSON 結構：

```
{
  "generated_at": "2026-04-15T10:00:00+00:00",
  "total_sites": 1114,
  "summary": {
    "critical": 0, "warning": 397, "info": 335, "ok": 382,
    "avg_complexity": 11.0, "avg_cost": 1.21
  },
  "reports": [...],
  "index_recommendations": {
    "order": [
      {
        "columns": ["user_id", "status"],
        "frequency": 12,
        "selectivities": {"user_id": 0.92, "status": 0.005},
        "replaces": ["idx_user"],
        "patterns": [...]
      }
    ]
  }
}
```

### 複合索引建議演算法

[](#複合索引建議演算法)

分析所有 call site 的 WHERE / ORDER BY 模式，依以下規則建構最優複合索引：

1. **Equality first** — 等值條件（`=`, `IN`, `IS NULL`）放在索引左側
2. **High selectivity first** — 等值欄位之間按選擇率（`COUNT(DISTINCT) / COUNT(*)`）由高到低排序
3. **Range last** — 範圍條件（`>`, ` env('SQL_MONITOR_ENABLED', true),
    'environments' => ['local', 'testing'],

    // 監控連線白/黑名單
    'connections'          => [],   // 空 = 監控所有連線
    'excluded_connections' => [],   // 永遠不監控（storage / IndexInspector 專用連線）

    // 持久化儲存（DB 層）— 問題查詢（慢查詢 / complexity >= warning / N+1 / duplicate）
    'storage' => [
        'driver'          => env('SQL_MONITOR_STORAGE_DRIVER', 'database'),
        // database（預設）：寫入 Laravel 應用程式的 DB，connection = null 時自動跟隨 database.default
        // sqlite：使用獨立 SQLite 檔案（完全不影響應用程式 DB）
        'database'        => env('SQL_MONITOR_STORAGE_DATABASE') ?: null,  // SQLite 路徑（database driver 不需要）
        'connection'      => env('SQL_MONITOR_STORAGE_CONNECTION') ?: null, // null = database.default
        'table'           => 'sql_monitor_logs',
        'retention_hours' => 24,
    ],

    // Cache 層 — 正常查詢（info / low），TTL 到期自動消失
    'memory' => [
        'enabled'    => true,
        'ttl'        => (int) env('SQL_MONITOR_MEMORY_TTL', 60),  // 每筆查詢存活秒數
        'max_buffer' => 500,
    ],

    // Dashboard 自動拉取間隔
    'dashboard' => [
        'polling_interval' => (int) env('SQL_MONITOR_POLLING_INTERVAL', 5),  // 秒
    ],

    // 靜態分析 log 輸出（tee 模式）
    'static_analysis' => [
        'output_path'    => env('SQL_MONITOR_ANALYSE_OUTPUT_PATH', storage_path('logs/sql-monitor')),
        // null / 空字串 = 不寫檔
        'analyse_log'    => env('SQL_MONITOR_ANALYSE_LOG',    'analyse-{date}.log'),
        'suggestion_log' => env('SQL_MONITOR_SUGGESTION_LOG', 'suggestion-{date}.log'),
        // {date} 佔位符會替換為當天日期（YYYY-MM-DD），每日自動旋轉
        // 同一天多次執行：append 模式，不覆蓋
        'log_format'     => env('SQL_MONITOR_ANALYSE_LOG_FORMAT', 'text'),
        // text = plain text（人讀）| json = JSON 格式
    ],

    // SQL 複雜度分析
    'complexity' => [
        'enabled'              => true,
        'persist_severity'     => env('SQL_MONITOR_PERSIST_SEVERITY', 'warning'),
        // 複雜度達到此等級（含）以上的查詢持久化到 DB 層
        // 可用值：low | info | warning（預設）| critical
        'join_threshold'       => 5,
        'subquery_depth_limit' => 3,
        'detect_select_star'   => true,
        'detect_missing_where' => true,
        'detect_like_wildcard' => true,
    ],

    // N+1 偵測
    'n1_detection' => [
        'enabled'   => true,
        'threshold' => 2,
    ],

    // 重複查詢偵測
    'duplicate_detection' => [
        'enabled' => true,
    ],

    // Slow Query 追蹤
    'slow_query' => [
        'enabled'      => true,
        'threshold_ms' => (int) env('SQL_MONITOR_SLOW_QUERY_THRESHOLD_MS', 100),
    ],

    // WebSocket 即時推送
    'live_monitor' => [
        'enabled'           => true,
        'broadcast_channel' => 'sql-monitor',
        'max_buffer_size'   => 1000,
    ],

    // Call Stack 收集
    'stack_trace' => [
        'enabled'         => true,
        'limit'           => 20,
        'exclude_vendors' => true,
    ],

    'ide'          => env('SQL_MONITOR_IDE', 'vscode'),
    'route_prefix' => 'sql-monitor',
    'middleware'    => ['web'],
];
```

### 常用 `.env` 設定

[](#常用-env-設定)

```
# 基本啟用
SQL_MONITOR_ENABLED=true

# storage driver（預設 database，使用應用程式的 DB）
SQL_MONITOR_STORAGE_DRIVER=database
# SQL_MONITOR_STORAGE_CONNECTION=   # null = database.default（留空即可）

# 若需要獨立 SQLite 檔案（不影響應用程式 DB）
# SQL_MONITOR_STORAGE_DRIVER=sqlite

# Cache 層 TTL（正常查詢在 Dashboard 的可見時間，秒）
SQL_MONITOR_MEMORY_TTL=60

# Dashboard polling 間隔（秒）
SQL_MONITOR_POLLING_INTERVAL=5

# 複雜度持久化閾值（warning = warning + critical 都寫入 DB）
SQL_MONITOR_PERSIST_SEVERITY=warning

# 靜態分析 log 輸出
SQL_MONITOR_ANALYSE_OUTPUT_PATH=storage/logs/sql-monitor
SQL_MONITOR_ANALYSE_LOG=analyse-{date}.log
SQL_MONITOR_SUGGESTION_LOG=suggestion-{date}.log
SQL_MONITOR_ANALYSE_LOG_FORMAT=text

# 慢查詢閾值（ms）
SQL_MONITOR_SLOW_QUERY_THRESHOLD_MS=100

# IDE 跳轉
SQL_MONITOR_IDE=vscode
```

---

動態分析
----

[](#動態分析)

套件在 `boot()` 時自動完成以下兩件事，**無需改動應用程式代碼**：

1. 監聽 `QueryExecuted` 事件（`QueryListener`）
2. 將 `QueryMonitoringMiddleware` 自動掛載到所有 HTTP request（全域 Middleware）

#### 持久化邏輯

[](#持久化邏輯)

條件寫入目的地時機執行時間 &gt;= `slow_query.threshold_ms`DB 層即時（QueryListener）複雜度 &gt;= `complexity.persist_severity`DB 層即時（QueryListener）N+1 pattern 代表查詢DB 層request 結束（Middleware）重複查詢代表查詢DB 層request 結束（Middleware）其餘查詢（info / low）Cache 層（TTL 60s）request 結束（Middleware）> `sql_monitor_logs` 資料表由套件自動建立（`ensureTableExists`），無需手動執行 migration。

### Web Dashboard

[](#web-dashboard)

訪問 `http://localhost:8000/sql-monitor` 查看：

- 查詢摘要與統計（DB 層歷史 + Cache 層近期，每 5 秒自動更新）
- N+1 警告面板
- 重複查詢面板
- 完整查詢日誌（可按 Slow / N+1 / Duplicate / Recent 篩選）
- 歷史慢查詢列表

### REST API

[](#rest-api)

```
GET  /sql-monitor/api/queries       查詢列表（DB 層，支援 is_slow / is_n1 / is_duplicate 等 filter）
GET  /sql-monitor/api/analytics     分析數據
GET  /sql-monitor/api/slow-queries  慢查詢
GET  /sql-monitor/api/stats         統計信息
GET  /sql-monitor/api/poll          Dashboard polling（DB 層 + Cache 層合併）
DELETE /sql-monitor/api/logs        清理日誌

```

### 在程式碼中讀取指標

[](#在程式碼中讀取指標)

```
use LaravelSqlMonitor\Lifecycle\RequestQueryManager;
use LaravelSqlMonitor\Monitor\MetricsCollector;

$manager = app(RequestQueryManager::class);
$count   = $manager->count();
$stats   = $manager->getStats(); // slow_query_count, n1_count, ...

$metrics = app(MetricsCollector::class)->collect();
```

---

支援的資料庫
------

[](#支援的資料庫)

### 動態分析

[](#動態分析-1)

- MySQL / MariaDB
- PostgreSQL
- SQLite
- SQL Server（基本）

### 靜態分析 — 索引檢查與選擇率計算

[](#靜態分析--索引檢查與選擇率計算)

- MySQL / MariaDB（完整支援：INFORMATION\_SCHEMA + COUNT DISTINCT）
- SQLite（基本：PRAGMA index\_list）
- PostgreSQL（待擴展）
- SQL Server（待擴展）

---

CI/CD 整合
--------

[](#cicd-整合)

```
# 只顯示 warning 以上，有 critical 時 exit code = 1
php artisan sql-monitor:analyse --min-severity=warning --no-index-recommend

# JSON 輸出供後續處理
php artisan sql-monitor:analyse --format=json > analyse.json
```

---

模組結構
----

[](#模組結構)

```
src/
├── StaticAnalysis/
│   ├── Ast/
│   │   ├── AstAnalyser.php              # PHP-Parser 驅動的 AST 掃描
│   │   ├── QueryChainExtractor.php      # 從 AST 節點提取查詢方法鏈
│   │   └── QueryCallSite.php            # 查詢呼叫點資料模型
│   ├── CallSiteAnalyser.php             # 規則引擎（偵測 no-limit / missing-index 等）
│   ├── CallSiteReport.php               # 分析結果資料模型
│   ├── CompositeIndexRecommender.php    # 複合索引建議演算法
│   └── IndexInspector.php               # DB 索引 / cardinality 查詢
│
├── Console/Commands/
│   └── AnalyseQueries.php              # sql-monitor:analyse 命令
│
├── Core/                               # 動態分析核心
│   ├── QueryAnalyzer.php
│   ├── ComplexityDetector.php
│   └── OptimizationSuggester.php
│
├── Lifecycle/
│   ├── N1QueryDetector.php
│   └── DuplicateQueryDetector.php
│
├── Monitor/
│   ├── SlowQueryTracker.php
│   └── LiveQueryMonitor.php
│
├── Storage/
│   ├── SqliteQueryStore.php
│   └── DatabaseQueryStore.php
│
└── Http/
    ├── Controllers/
    └── Routes/

```

---

License
-------

[](#license)

MIT License © 2026.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance81

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 65.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

11

Last Release

98d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/107267538?v=4)[Denny-Chu](/maintainers/Denny-Chu)[@Denny-Chu](https://github.com/Denny-Chu)

---

Top Contributors

[![Denny168m](https://avatars.githubusercontent.com/u/224479731?v=4)](https://github.com/Denny168m "Denny168m (17 commits)")[![Denny-Chu](https://avatars.githubusercontent.com/u/107267538?v=4)](https://github.com/Denny-Chu "Denny-Chu (9 commits)")

---

Tags

laraveldebugperformancesqlquerymonitor

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/denny-laravel-sql-monitor/health.svg)

```
[![Health](https://phpackages.com/badges/denny-laravel-sql-monitor/health.svg)](https://phpackages.com/packages/denny-laravel-sql-monitor)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k30.2M151](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M136](/packages/laravel-pulse)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1235.9k21](/packages/fleetbase-core-api)[calebdw/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

15118.7k4](/packages/calebdw-larastan)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
