{"id":18010821,"url":"https://github.com/guanguans/laravel-soar","last_synced_at":"2026-04-02T19:25:30.321Z","repository":{"id":41264167,"uuid":"275145311","full_name":"guanguans/laravel-soar","owner":"guanguans","description":"SQL optimizer and rewriter for laravel. - laravel 的 SQL 优化器和重写器。","archived":false,"fork":false,"pushed_at":"2026-03-27T07:38:34.000Z","size":43551,"stargazers_count":222,"open_issues_count":0,"forks_count":9,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-27T19:35:32.321Z","etag":null,"topics":["clockwork","debug","debugbar","laravel","laravel-sql","mysql","optimize","optimizer","ray","rewrite","rewriter","security-vulnerabilities","soar","sql","sql-optimizer","statement"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/guanguans.png","metadata":{"files":{"readme":"README-zh_CN.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":"https://guanguans.github.io/sponsors"}},"created_at":"2020-06-26T11:58:41.000Z","updated_at":"2026-03-27T07:38:30.000Z","dependencies_parsed_at":"2023-02-09T18:32:05.085Z","dependency_job_id":"2fac80e5-d963-4f33-a060-526dadaf0997","html_url":"https://github.com/guanguans/laravel-soar","commit_stats":{"total_commits":186,"total_committers":7,"mean_commits":"26.571428571428573","dds":"0.25268817204301075","last_synced_commit":"23278d71b848d3b473264a55eaa9e787358e7be2"},"previous_names":[],"tags_count":92,"template":false,"template_full_name":null,"purl":"pkg:github/guanguans/laravel-soar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanguans%2Flaravel-soar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanguans%2Flaravel-soar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanguans%2Flaravel-soar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanguans%2Flaravel-soar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guanguans","download_url":"https://codeload.github.com/guanguans/laravel-soar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanguans%2Flaravel-soar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31314377,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clockwork","debug","debugbar","laravel","laravel-sql","mysql","optimize","optimizer","ray","rewrite","rewriter","security-vulnerabilities","soar","sql","sql-optimizer","statement"],"created_at":"2024-10-30T02:15:26.213Z","updated_at":"2026-04-02T19:25:30.313Z","avatar_url":"https://github.com/guanguans.png","language":"PHP","funding_links":["https://guanguans.github.io/sponsors"],"categories":["PHP"],"sub_categories":[],"readme":"| ![](docs/soar-bar.gif) | ![](docs/commands.gif) |\n|------------------------|------------------------|\n\n# laravel-soar\n\n\u003e SQL optimizer and rewriter for laravel. - laravel 的 SQL 优化器和重写器。\n\n[简体中文](README-zh_CN.md) | [ENGLISH](README.md)\n\n[![tests](https://github.com/guanguans/laravel-soar/actions/workflows/tests.yml/badge.svg)](https://github.com/guanguans/laravel-soar/actions/workflows/tests.yml)\n[![php-cs-fixer](https://github.com/guanguans/laravel-soar/actions/workflows/php-cs-fixer.yml/badge.svg)](https://github.com/guanguans/laravel-soar/actions/workflows/php-cs-fixer.yml)\n[![codecov](https://codecov.io/gh/guanguans/laravel-soar/graph/badge.svg?token=EWBG8GV4JD)](https://codecov.io/gh/guanguans/laravel-soar)\n[![Latest Stable Version](https://poser.pugx.org/guanguans/laravel-soar/v)](https://packagist.org/packages/guanguans/laravel-soar)\n[![GitHub release (with filter)](https://img.shields.io/github/v/release/guanguans/laravel-soar)](https://github.com/guanguans/laravel-soar/releases)\n[![Total Downloads](https://poser.pugx.org/guanguans/laravel-soar/downloads)](https://packagist.org/packages/guanguans/laravel-soar)\n[![License](https://poser.pugx.org/guanguans/laravel-soar/license)](https://packagist.org/packages/guanguans/laravel-soar)\n\n## 功能\n\n* 支持启发式规则建议、索引规则建议、`EXPLAIN` 信息解读\n* 支持调用查询构建器 `Mixin` 方法便捷的打印规则建议\n* 自动监控输出规则建议到配置的输出器\n\n## 相关项目\n\n* [https://github.com/XiaoMi/soar](https://github.com/XiaoMi/soar)\n* [https://github.com/guanguans/soar-php](https://github.com/guanguans/soar-php)\n\n## 环境要求\n\n* PHP \u003e= 8.2\n\n## 安装\n\n```shell\ncomposer require guanguans/laravel-soar --dev --ansi -v\n```\n\n## 配置\n\n### 发布文件(可选的)\n\n```shell\nphp artisan vendor:publish --provider=\"Guanguans\\\\LaravelSoar\\\\SoarServiceProvider\"\n```\n\n### :warning: 在 unix 操作系统非 cli 环境中运行时，可能会抛出 Fatal error: ...Exit Code: 2(Misuse of shell builtins)\n\n#### 配置 sudo 密码\n\n```shell\n# Fatal error: Uncaught Guanguans\\SoarPHP\\Exceptions\\ProcessFailedException: The command \"'/Users/yaozm/Documents/develop/soar-php/bin/soar.darwin-amd64' '-report-type=json' '-query=select * from users;'\" failed. Exit Code: 2(Misuse of shell builtins) Working directory: /Users/yaozm/Documents/develop/soar-php Output: ================ Error Output: ================ panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1938665] goroutine 1 [running]: github.com/pingcap/tidb/util/memory.MemTotalNormal() pkg/mod/github.com/pingcap/tidb@v1.1.0-beta.0.20210601085537-5d7c852770eb/util/memory/meminfo.go:41 +0x65 github.com/pingcap/tidb/util/memory.init.0() pkg/mod/github.com/pingcap/tidb@v1.1.0-beta.0.20210601085537-5d7c852770eb/util/memory/meminfo.go:134 +0x175 in /Users/yaozm/Documents/develop/soar-php/src/Concerns/WithRunable.php:36 Stack trace: #0 /Users/yaozm/Documents/develop/soar-php/test.php(163): Guanguans\\SoarPHP\\Soar-\u003erun() #1 /User in /Users/yaozm/Documents/develop/soar-php/src/Concerns/WithRunable.php on line 36\nSOAR_SUDO_PASSWORD='your sudo password' # 设置 sudo 密码，以 sudo 运行 soar 命令，避免出现上述错误。\n```\n\n#### [或者配置 sudoers](https://github.com/guanguans/soar-php#or-configure-sudoers)\n\n## 使用\n\n### 启用自动输出 SQL 优化建议\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003edetails\u003c/b\u003e\u003c/summary\u003e\n\n#### 配置 `SOAR_ENABLED`\n\n```dotenv\nSOAR_ENABLED=true\n```\n\n#### 或者配置 [`soar.enabled`](config/soar.php)\n\n```php\n\u003c?php\n\nreturn [\n    'enabled' =\u003e (bool) env('SOAR_ENABLED', env('APP_ENV') === 'local'),\n\n    // ...\n];\n```\n\u003c/details\u003e\n\n### 安装、配置输出器(可选的)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eClockwork\u003c/b\u003e\u003c/summary\u003e\n\n1. 安装 [itsgoingd/clockwork](https://github.com/itsgoingd/clockwork)\n2. 配置 [soar.outputs.Outputs\\ClockworkOutput::class](config/soar.php)\n\n![Clockwork](docs/clockwork.png)\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eConsole\u003c/b\u003e\u003c/summary\u003e\n\n1. 配置 [soar.outputs.Outputs\\ConsoleOutput::class](config/soar.php)\n\n![Console](docs/console.png)\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eDebug bar\u003c/b\u003e\u003c/summary\u003e\n\n1. 安装 [fruitcake/laravel-debugbar](https://github.com/fruitcake/laravel-debugbar)\n2. 配置 [soar.outputs.Outputs\\DebugBarOutput::class](config/soar.php)\n\n![DebugBar](docs/debug-bar.png)\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eDump\u003c/b\u003e\u003c/summary\u003e\n\n1. 配置 [soar.outputs.Outputs\\DumpOutput::class](config/soar.php)\n\n![Dump](docs/dump.png)\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eJson\u003c/b\u003e\u003c/summary\u003e\n\n1. 配置 [soar.outputs.Outputs\\JsonOutput::class](config/soar.php)\n\n```json\n{\n    \"message\": \"ok\",\n    \"soar_scores\": [\n        {\n            \"Summary\": \"[☆☆☆☆☆|0分|9.17ms|select * from `users` where `name` = 'soar' group by `name` having `created_at` \u003e '2023-06-05 03:19:30']\",\n            \"Basic\": {\n                \"Sample\": \"select * from `users` where `name` = 'soar' group by `name` having `created_at` \u003e '2023-06-05 03:19:30'\",\n                \"Score\": 0,\n                \"Star\": \"☆☆☆☆☆\",\n                \"Time\": \"9.17ms\",\n                \"Connection\": \"mysql\",\n                \"Driver\": \"mysql\",\n                \"Tables\": [\n                    \"`laravel`.`users`\"\n                ]\n            },\n            \"HeuristicRules\": [\n                {\n                    \"Item\": \"CLA.008\",\n                    \"Severity\": \"L2\",\n                    \"Summary\": \"请为 GROUP BY 显示添加 ORDER BY 条件\",\n                    \"Content\": \"默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生，如果不需要排序建议添加 'ORDER BY NULL'。\",\n                    \"Case\": \"select c1,c2,c3 from t1 where c1='foo' group by c2\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"CLA.013\",\n                    \"Severity\": \"L3\",\n                    \"Summary\": \"不建议使用 HAVING 子句\",\n                    \"Content\": \"将查询的 HAVING 子句改写为 WHERE 中的查询条件，可以在查询处理期间使用索引。\",\n                    \"Case\": \"SELECT s.c_id,count(s.c_id) FROM s where c = test GROUP BY s.c_id HAVING s.c_id \u003c\u003e '1660' AND s.c_id \u003c\u003e '2' order by s.c_id\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"COL.001\",\n                    \"Severity\": \"L1\",\n                    \"Summary\": \"不建议使用 SELECT * 类型查询\",\n                    \"Content\": \"当表结构变更时，使用 * 通配符选择所有列将导致查询的含义和行为会发生更改，可能导致查询返回更多的数据。\",\n                    \"Case\": \"select * from tbl where id=1\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"ERR.002\",\n                    \"Severity\": \"L8\",\n                    \"Summary\": \"MySQL execute failed\",\n                    \"Content\": \"Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'optimizer_230605111934_bbpxve0adj2dgrcs.users.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by\",\n                    \"Case\": \"\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"GRP.001\",\n                    \"Severity\": \"L2\",\n                    \"Summary\": \"不建议对等值查询列使用 GROUP BY\",\n                    \"Content\": \"GROUP BY 中的列在前面的 WHERE 条件中使用了等值查询，对这样的列进行 GROUP BY 意义不大。\",\n                    \"Case\": \"select film_id, title from film where release_year='2006' group by release_year\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"RES.001\",\n                    \"Severity\": \"L4\",\n                    \"Summary\": \"非确定性的 GROUP BY\",\n                    \"Content\": \"SQL返回的列既不在聚合函数中也不是 GROUP BY 表达式的列中，因此这些值的结果将是非确定性的。如：select a, b, c from tbl where foo=\\\"bar\\\" group by a，该 SQL 返回的结果就是不确定的。\",\n                    \"Case\": \"select c1,c2,c3 from t1 where c2='foo' group by c2\",\n                    \"Position\": 0\n                }\n            ],\n            \"IndexRules\": [\n                {\n                    \"Item\": \"IDX.001\",\n                    \"Severity\": \"L2\",\n                    \"Summary\": \"为laravel库的users表添加索引\",\n                    \"Content\": \"为列name添加索引;为列created_at添加索引; 由于未开启数据采样，各列在索引中的顺序需要自行调整。\",\n                    \"Case\": \"ALTER TABLE `laravel`.`users` add index `idx_name_created_at` (`name`(191),`created_at`) ;\\n\",\n                    \"Position\": 0\n                }\n            ],\n            \"Explain\": [],\n            \"Backtraces\": [\n                \"#13 /routes/web.php:53\",\n                \"#38 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:37\",\n                \"#59 /public/index.php:55\",\n                \"#60 /server.php:21\"\n            ]\n        },\n        {\n            \"Summary\": \"[★★★★☆|75分|205.25ms|CREATE TABLE `users` (\\n  `id` bigint unsigned NOT NULL AUTO_INCREMENT,\\n  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,\\n  `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,\\n  `email_verified_at` timestamp NULL DEFAULT NULL,\\n  `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,\\n  `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\\n  `created_at` timestamp NULL DEFAULT NULL,\\n  `updated_at` timestamp NULL DEFAULT NULL,\\n  PRIMARY KEY (`id`),\\n  UNIQUE KEY `users_email_unique` (`email`)\\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;]\",\n            \"Basic\": {\n                \"Sample\": \"CREATE TABLE `users` (\\n  `id` bigint unsigned NOT NULL AUTO_INCREMENT,\\n  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,\\n  `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,\\n  `email_verified_at` timestamp NULL DEFAULT NULL,\\n  `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,\\n  `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\\n  `created_at` timestamp NULL DEFAULT NULL,\\n  `updated_at` timestamp NULL DEFAULT NULL,\\n  PRIMARY KEY (`id`),\\n  UNIQUE KEY `users_email_unique` (`email`)\\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\",\n                \"Score\": 75,\n                \"Star\": \"★★★★☆\",\n                \"Time\": \"205.25ms\",\n                \"Connection\": \"mysql\",\n                \"Driver\": \"mysql\",\n                \"Tables\": [\n                    \"`laravel`.`users`\"\n                ]\n            },\n            \"HeuristicRules\": [\n                {\n                    \"Item\": \"CLA.011\",\n                    \"Severity\": \"L1\",\n                    \"Summary\": \"建议为表添加注释\",\n                    \"Content\": \"为表添加注释能够使得表的意义更明确，从而为日后的维护带来极大的便利。\",\n                    \"Case\": \"CREATE TABLE `test1` (`ID` bigint(20) NOT NULL AUTO_INCREMENT,`c1` varchar(128) DEFAULT NULL,PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"COL.004\",\n                    \"Severity\": \"L1\",\n                    \"Summary\": \"请为列添加默认值\",\n                    \"Content\": \"请为列添加默认值，如果是 ALTER 操作，请不要忘记将原字段的默认值写上。字段无默认值，当表较大时无法在线变更表结构。\",\n                    \"Case\": \"CREATE TABLE tbl (col int) ENGINE=InnoDB;\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"COL.005\",\n                    \"Severity\": \"L1\",\n                    \"Summary\": \"列未添加注释\",\n                    \"Content\": \"建议对表中每个列添加注释，来明确每个列在表中的含义及作用。\",\n                    \"Case\": \"CREATE TABLE tbl (col int) ENGINE=InnoDB;\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"KWR.003\",\n                    \"Severity\": \"L1\",\n                    \"Summary\": \"不建议使用复数做列名或表名\",\n                    \"Content\": \"表名应该仅仅表示表里面的实体内容，不应该表示实体数量，对应于 DO 类名也是单数形式，符合表达习惯。\",\n                    \"Case\": \"CREATE TABLE tbl ( `books` int )\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"SEC.002\",\n                    \"Severity\": \"L0\",\n                    \"Summary\": \"不使用明文存储密码\",\n                    \"Content\": \"使用明文存储密码或者使用明文在网络上传递密码都是不安全的。如果攻击者能够截获您用来插入密码的SQL语句，他们就能直接读到密码。另外，将用户输入的字符串以明文的形式插入到纯SQL语句中，也会让攻击者发现它。如果您能够读取密码，黑客也可以。解决方案是使用单向哈希函数对原始密码进行加密编码。哈希是指将输入字符串转化成另一个新的、不可识别的字符串的函数。对密码加密表达式加点随机串来防御“字典攻击”。不要将明文密码输入到SQL查询语句中。在应用程序代码中计算哈希串，只在SQL查询中使用哈希串。\",\n                    \"Case\": \"create table test(id int,name varchar(20) not null,password varchar(200)not null)\",\n                    \"Position\": 0\n                },\n                {\n                    \"Item\": \"STA.003\",\n                    \"Severity\": \"L1\",\n                    \"Summary\": \"索引起名不规范\",\n                    \"Content\": \"建议普通二级索引以idx_为前缀，唯一索引以uk_为前缀。\",\n                    \"Case\": \"select col from now where type!=0\",\n                    \"Position\": 0\n                }\n            ],\n            \"IndexRules\": [],\n            \"Explain\": [],\n            \"Backtraces\": [\n                \"#9 /routes/web.php:22\",\n                \"#34 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:37\",\n                \"#55 /public/index.php:55\",\n                \"#56 /server.php:21\"\n            ]\n        },\n        {\n            \"Summary\": \"[★★★★☆|80分|1.72ms|update `users` set `name` = 'name', `password` = 'password', `users`.`updated_at` = '2023-06-05 03:19:30']\",\n            \"Basic\": {\n                \"Sample\": \"update `users` set `name` = 'name', `password` = 'password', `users`.`updated_at` = '2023-06-05 03:19:30'\",\n                \"Score\": 80,\n                \"Star\": \"★★★★☆\",\n                \"Time\": \"1.72ms\",\n                \"Connection\": \"mysql\",\n                \"Driver\": \"mysql\",\n                \"Tables\": [\n                    \"`laravel`.`users`\"\n                ]\n            },\n            \"HeuristicRules\": [\n                {\n                    \"Item\": \"CLA.015\",\n                    \"Severity\": \"L4\",\n                    \"Summary\": \"UPDATE 未指定 WHERE 条件\",\n                    \"Content\": \"UPDATE 不指定 WHERE 条件一般是致命的，请您三思后行\",\n                    \"Case\": \"update tbl set col=1\",\n                    \"Position\": 0\n                }\n            ],\n            \"IndexRules\": [],\n            \"Explain\": [\n                {\n                    \"Item\": \"EXP.000\",\n                    \"Severity\": \"L0\",\n                    \"Summary\": \"Explain信息\",\n                    \"Content\": [\n                        \"| id | select\\\\_type | table | partitions | type | possible_keys | key | key\\\\_len | ref | rows | filtered | scalability | Extra |\",\n                        \"|---|---|---|---|---|---|---|---|---|---|---|---|---|\",\n                        \"| 1  | UPDATE | *users* | NULL | index | NULL | PRIMARY | 8 | NULL | 1 | ☠️ **100.00%** | ☠️ **O(n)** | NULL |\"\n                    ],\n                    \"Case\": [\n                        \"### Explain信息解读\",\n                        \"#### Type信息解读\",\n                        \"* **index**: 全表扫描, 只是扫描表的时候按照索引次序进行而不是行. 主要优点就是避免了排序, 但是开销仍然非常大.\"\n                    ],\n                    \"Position\": 0\n                }\n            ],\n            \"Backtraces\": [\n                \"#10 /routes/web.php:48\",\n                \"#35 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:37\",\n                \"#56 /public/index.php:55\",\n                \"#57 /server.php:21\"\n            ]\n        },\n        {\n            \"Summary\": \"[★★★★★|90分|940μs|delete from `users` where `name` = 'soar']\",\n            \"Basic\": {\n                \"Sample\": \"delete from `users` where `name` = 'soar'\",\n                \"Score\": 90,\n                \"Star\": \"★★★★★\",\n                \"Time\": \"940μs\",\n                \"Connection\": \"mysql\",\n                \"Driver\": \"mysql\",\n                \"Tables\": [\n                    \"`laravel`.`users`\"\n                ]\n            },\n            \"HeuristicRules\": [\n                {\n                    \"Item\": \"SEC.003\",\n                    \"Severity\": \"L0\",\n                    \"Summary\": \"使用DELETE/DROP/TRUNCATE等操作时注意备份\",\n                    \"Content\": \"在执行高危操作之前对数据进行备份是十分有必要的。\",\n                    \"Case\": \"delete from table where col = 'condition'\",\n                    \"Position\": 0\n                }\n            ],\n            \"IndexRules\": [\n                {\n                    \"Item\": \"IDX.001\",\n                    \"Severity\": \"L2\",\n                    \"Summary\": \"为laravel库的users表添加索引\",\n                    \"Content\": \"为列name添加索引; 由于未开启数据采样，各列在索引中的顺序需要自行调整。\",\n                    \"Case\": \"ALTER TABLE `laravel`.`users` add index `idx_name` (`name`(191)) ;\\n\",\n                    \"Position\": 0\n                }\n            ],\n            \"Explain\": [\n                {\n                    \"Item\": \"EXP.000\",\n                    \"Severity\": \"L0\",\n                    \"Summary\": \"Explain信息\",\n                    \"Content\": [\n                        \"| id | select\\\\_type | table | partitions | type | possible_keys | key | key\\\\_len | ref | rows | filtered | scalability | Extra |\",\n                        \"|---|---|---|---|---|---|---|---|---|---|---|---|---|\",\n                        \"| 1  | DELETE | *users* | NULL | ALL | NULL | NULL | NULL | NULL | 1 | ☠️ **100.00%** | ☠️ **O(n)** | Using where |\"\n                    ],\n                    \"Case\": [\n                        \"### Explain信息解读\",\n                        \"#### Type信息解读\",\n                        \"* ☠️ **ALL**: 最坏的情况, 从头到尾全表扫描.\",\n                        \"#### Extra信息解读\",\n                        \"* **Using where**: WHERE条件用于筛选出与下一个表匹配的数据然后返回给客户端. 除非故意做的全表扫描, 否则连接类型是ALL或者是index, 且在Extra列的值中没有Using Where, 则该查询可能是有问题的.\"\n                    ],\n                    \"Position\": 0\n                }\n            ],\n            \"Backtraces\": [\n                \"#10 /routes/web.php:56\",\n                \"#35 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:37\",\n                \"#56 /public/index.php:55\",\n                \"#57 /server.php:21\"\n            ]\n        },\n        {\n            \"Summary\": \"[★★★★★|100分|9.59ms|insert into `users` (`name`, `email`, `email_verified_at`, `password`, `remember_token`) values ('soar', 'soar@soar.com', '2023-06-05 03:19:30', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'lEtsoV3wHW')]\",\n            \"Basic\": {\n                \"Sample\": \"insert into `users` (`name`, `email`, `email_verified_at`, `password`, `remember_token`) values ('soar', 'soar@soar.com', '2023-06-05 03:19:30', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'lEtsoV3wHW')\",\n                \"Score\": 100,\n                \"Star\": \"★★★★★\",\n                \"Time\": \"9.59ms\",\n                \"Connection\": \"mysql\",\n                \"Driver\": \"mysql\",\n                \"Tables\": [\n                    \"`laravel`.`users`\"\n                ]\n            },\n            \"HeuristicRules\": [],\n            \"IndexRules\": [],\n            \"Explain\": [\n                {\n                    \"Item\": \"EXP.000\",\n                    \"Severity\": \"L0\",\n                    \"Summary\": \"Explain信息\",\n                    \"Content\": [\n                        \"| id | select\\\\_type | table | partitions | type | possible_keys | key | key\\\\_len | ref | rows | filtered | scalability | Extra |\",\n                        \"|---|---|---|---|---|---|---|---|---|---|---|---|---|\",\n                        \"| 1  | INSERT | *users* | NULL | ALL | NULL | NULL | NULL | NULL | 0 | 0.00% | ☠️ **O(n)** | NULL |\"\n                    ],\n                    \"Case\": [\n                        \"### Explain信息解读\",\n                        \"#### Type信息解读\",\n                        \"* ☠️ **ALL**: 最坏的情况, 从头到尾全表扫描.\"\n                    ],\n                    \"Position\": 0\n                }\n            ],\n            \"Backtraces\": [\n                \"#10 /routes/web.php:43\",\n                \"#35 /Users/yaozm/Documents/develop/laravel-soar/src/Http/Middleware/OutputSoarScoreMiddleware.php:37\",\n                \"#56 /public/index.php:55\",\n                \"#57 /server.php:21\"\n            ]\n        }\n    ]\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eLaraDumps\u003c/b\u003e\u003c/summary\u003e\n\n1. 安装 [laradumps/laradumps](https://github.com/laradumps/laradumps)\n2. 配置 [soar.outputs.Outputs\\LaraDumpsOutput::class](config/soar.php)\n\n![LaraDumps](docs/lara-dumps.png)\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eLog\u003c/b\u003e\u003c/summary\u003e\n\n1. 配置 [soar.outputs.Outputs\\LogOutput::class](config/soar.php)\n\n![Log](docs/log.png)\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eRay\u003c/b\u003e\u003c/summary\u003e\n\n1. 安装 [spatie/laravel-ray](https://github.com/spatie/laravel-ray)\n2. 配置 [soar.outputs.Outputs\\RayOutput::class](config/soar.php)\n\n![Ray](docs/ray.png)\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eTelescope\u003c/b\u003e\u003c/summary\u003e\n\nTelescope 的 `EventWatcher` 和 `LogWatcher` 可观察到 Soar 评分的输出。\n\n1. 安装 [laravel/telescope](https://github.com/laravel/telescope)\n2. 配置 `telescope.watchers`：\n\n```php\n\u003c?php\n\nuse Laravel\\Telescope\\Watchers;\n\nreturn [\n    // ...\n\n    'watchers' =\u003e [\n        // ...\n\n        Watchers\\EventWatcher::class =\u003e [\n            'enabled' =\u003e env('TELESCOPE_EVENT_WATCHER', true),\n            'ignore' =\u003e [\n                Guanguans\\LaravelSoar\\Events\\OutputtedEvent::class, // ignore `OutputtedEvent`\n            ],\n        ],\n\n        // ...\n\n        Watchers\\LogWatcher::class =\u003e [\n            'enabled' =\u003e env('TELESCOPE_LOG_WATCHER', true),\n            'level' =\u003e 'warning', // `warning` level\n        ],\n\n        // ...\n    ],\n];\n```\n\n| ![Telescope event](docs/telescope-event.png) | ![Telescope log](docs/telescope-log.png) |\n|----------------------------------------------|------------------------------------------|\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e自定义输出器\u003c/b\u003e\u003c/summary\u003e\n\n1. 实现 [OutputContract](src/Contracts/OutputContract.php)\n2. 配置 [soar.outputs.Outputs\\CustomOutput::class](config/soar.php)\n\u003c/details\u003e\n\n### Soar 命令\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003edetails\u003c/b\u003e\u003c/summary\u003e\n\n```shell\n╰─ php artisan                                                                            ─╯\n...\nAvailable commands:\n...\n soar\n  soar:clear                            Clear the Soar log file\n  soar:run                              Run Soar with the given options\n  soar:score                            Get the Soar scores of the given SQL statements\n...\n```\n\n#### 使用示例(支持标准输入)\n\n```shell\necho 'select * from foo; select * from bar;' | php artisan soar:score --ansi\nphp artisan soar:score --ansi\nphp artisan soar:score --ansi --option=-query='select * from foo; select * from bar;'\nphp artisan soar:score --ansi \u003c tests/Fixtures/queries.sql\n```\n\n![commands](docs/commands.gif)\n\u003c/details\u003e\n\n### [Soar 门面及方法](src/Facades/Soar.php)\n\n### 查询构建器 [`Mixin`](src/Mixins/QueryBuilderMixin.php) 的[方法](_ide_helper.php)\n\n## Composer 脚本\n\n```shell\ncomposer checks:required\ncomposer php-cs-fixer:fix\ncomposer test\ncomposer testbench soar:run\ncomposer testbench soar:score\ncomposer testbench:serve\ncomposer testbench:test\ncomposer testbench:user-serve\n```\n\n## 变更日志\n\n请参阅 [CHANGELOG](CHANGELOG.md) 获取最近有关更改的更多信息。\n\n## 贡献指南\n\n请参阅 [CONTRIBUTING](.github/CONTRIBUTING.md) 有关详细信息。\n\n## 安全漏洞\n\n请查看[我们的安全政策](../../security/policy)了解如何报告安全漏洞。\n\n## 贡献者\n\n* [guanguans](https://github.com/guanguans)\n* [所有贡献者](../../contributors)\n\n## 协议\n\nMIT 许可证(MIT)。有关更多信息，请参见[协议文件](LICENSE)。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguanguans%2Flaravel-soar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguanguans%2Flaravel-soar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguanguans%2Flaravel-soar/lists"}