内容
# ClickAdvisor
# https://clickadvisor.lovable.app




> 本地优先的 ClickHouse 查询优化 CLI 和 MCP 顾问。
> Находит SQL-антипаттерны, показывает формально обоснованные rewrite-рекомендации, дополняет их retrieval-контекстом из KB и при необходимости оценивает влияние через `EXPLAIN ESTIMATE`.

- 建议与 `rule_id`、tier 和 ClickHouse 版本绑定;
- Tier `1A/1B/1C` 明确区分正式的重写规则和条件性建议;
- retrieval advisory 添加文档链接,但不取代规则引擎;
- `EXPLAIN ESTIMATE` 可以在不执行 `ANALYZE` 和不读取用户数据的情况下,评估行数和标记数的影响;
- MCP 服务器允许从 Claude Desktop、Cursor、Continue 等代理调用相同的本地分析。
## 功能 v1.0
- 21+ 条规则和检测器适用于 ClickHouse SQL (`R-001`…`R-018`, `D-003`, `D-004`, `D-007`)
- 基于 `--ch-version` 或通过 `--connect` 自动检测的版本感知过滤
- 控制台 / JSON / Markdown 报告
- `--mode explain` 模式,提供教育性解释
- 通过嵌入式 Qdrant 知识库的基于检索的建议
- 索引知识库时选择嵌入模型
- 可选的 `EXPLAIN ESTIMATE` 影响摘要
- 带有工具和提示的标准输入输出 MCP 服务器
- 用于嵌入模型的合成基准和消融实验
## 快速开始
### 从源码
```bash
git clone https://github.com/olyannaa/clickadvisor.git
cd clickadvisor
poetry install
poetry run chadvisor analyze --sql examples/bad_query.sql
```
### pip
```bash
pip install clickadvisor # 待软件包发布后
chadvisor analyze --sql examples/bad_query.sql
```
### Docker
```bash
docker run --rm -v $(pwd):/queries \
ghcr.io/username/clickadvisor:latest \
analyze --sql /queries/query.sql
```
## CLI 使用
### 基本分析
```bash
poetry run chadvisor analyze --sql query.sql
```
### 指定 ClickHouse 版本
```bash
poetry run chadvisor analyze --sql query.sql --ch-version 25.3
```
### 通过 HTTP API 自动检测版本
```bash
poetry run chadvisor analyze --sql query.sql \
--connect http://host:8123 \
--ch-user default \
--ch-password secret
```
### 解释模式
```bash
poetry run chadvisor analyze --sql query.sql --mode explain
```
### 输出格式
```bash
poetry run chadvisor analyze --sql query.sql --output-format json
poetry run chadvisor analyze --sql query.sql --output-format markdown
```
### `EXPLAIN ESTIMATE` 影响
如果指定 `--connect`,ClickAdvisor 可以对原始 SQL 和规则重写(`example_after`)执行 `EXPLAIN ESTIMATE`,并添加一行 `📊 影响`:
```bash
poetry run chadvisor analyze --sql query.sql \
--connect http://localhost:8123 \
--explain-estimate
```
这不会运行 `ANALYZE`,也不会读取用户数据;使用 ClickHouse 调度器(`rows`、`marks`)的评估。
## 检索顾问知识库
索引知识库会从 `data/kb/chunks/` 创建嵌入式 Qdrant 数据库 `.qdrant_db`:
```bash
poetry run chadvisor index-kb
```
重新索引:
```bash
poetry run chadvisor index-kb --reindex
```
选择嵌入模型:
```bash
poetry run chadvisor index-kb --embedding-model multilingual-e5-small
poetry run chadvisor index-kb --embedding-model minilm-l6
```
可用模型:
| 键 | 模型 | 尺寸 | 备注 |
|---|---|---:|---|
| `multilingual-e5-small` | `intfloat/multilingual-e5-small` | 117 MB | 默认,多语言,E5 前缀 |
| `minilm-l6` | `sentence-transformers/all-MiniLM-L6-v2` | 80 MB | 仅限英语,更快,当前英语知识库的最佳 MRR@3 |
如果存在 `.qdrant_db`,则 `analyze` 命令默认添加 RAG 查找,单独显示为 `📚 相关文档`。管理:
```bash
poetry run chadvisor analyze --sql query.sql --retrieval
poetry run chadvisor analyze --sql query.sql --no-retrieval
```
## MCP 服务器
ClickAdvisor 提供标准输入输出 MCP 服务器:
```bash
poetry run chadvisor mcp-server
```
适用于 Claude Desktop、Cursor、Continue 等客户端的详细说明:[`docs/MCP.md`](docs/MCP.md)。
MCP 工具:
- `analyze_query` — SQL 的 Markdown 报告
- `analyze_query_json` — 结构化 JSON,无 RAG 查找
- `list_rules` — 规则列表
- `detect_ch_version` — 通过 HTTP API 检测 ClickHouse 版本
MCP 提示:
- `analyze`
- `explain`
## 规则和覆盖
| 规则 ID | 描述 | 级别 |
|---|---|---|
| `R-001` | `COUNT(DISTINCT x)` → `uniqExact(x)` | `1A` |
| `R-002` | `COUNT(DISTINCT x)` → 建议 `uniq(x)` | `1B` |
| `R-003` | `quantileExact(...)` → 建议 `quantileTDigest(...)` | `1B` |
| `R-004` | `COUNT(*) FROM (SELECT DISTINCT ...)` 折叠 | `1A` |
| `R-005` | `toDate(col) = ...` → 日期范围 | `1A` |
| `R-006` | `toYYYYMM(...)` / `toStartOfMonth(...)` → 范围 | `1A` |
| `R-007` | `toStartOfHour/Day/FifteenMinutes(...)` → 范围 | `1A` |
| `R-008` | 冗余的 `CAST(...)` 在过滤器中 | `1C` |
| `R-009` | 单例 `IN (...)` → 等式 | `1A` |
| `R-010` | `col = a OR col = b OR col = c` → `IN (...)` | `1A` |
| `R-011` | 非聚合谓词在 `HAVING` → `WHERE` | `1C` |
| `R-012` | 常量谓词消除 | `1A` |
| `R-013` | `length(x) = 0 / > 0 / != 0` → `empty/notEmpty` | `1A` |
| `R-014` | 建议基于哈希的 `GROUP BY` 用于长字符串 | `1B` |
| `R-015` | 等效 `GROUP BY` 删除后 `DISTINCT` | `1A` |
| `R-016` | 子查询中无 `LIMIT` 的 `ORDER BY` | `1C` |
| `R-017` | 子查询过滤器下推 | `1A` |
| `R-018` | 建议 `UNION` → `UNION ALL` | `1C` |
| `D-003` | 顶级 `SELECT *` 检测器 | `detector` |
| `D-004` | 非聚合顶级选择中缺少 `LIMIT` | `detector` |
| `D-007` | 成本高的 `FINAL` 修饰符检测器 | `detector` |
## 质量指标
合成基准:
```bash
poetry run python scripts/eval/run_benchmark.py
```
当前精选合成基准(`lenient` 模式):精度/召回率/F1 得分应保持在 `1.00` 以供规则检测。
嵌入消融:
```bash
poetry run python scripts/eval/ablation_embeddings.py
```
最新的 2000-chunk 消融报告 MRR@3 在合成案例上,并打印推荐。在英语为主的知识库上,`all-MiniLM-L6-v2` 具有最佳 MRR@3,但默认保留多语言 E5;参见 [`docs/adr/ADR-013-embedding-model-selection.md`](docs/adr/ADR-013-embedding-model-selection.md)。
## 架构
```text
SQL + Schema + 可选 EXPLAIN / CH 版本
↓
SQL 解析器 (sqlglot)
↓
┌──────────────────┐
│ 规则引擎 │
│ ├─ Tier 1A: 形式等效重写
│ ├─ Tier 1B: 近似 / 选择性指导
│ ├─ Tier 1C: 条件重写
│ └─ 检测器: 反模式检测
└──────────────────┘
↓
版本过滤器 + 可选 EXPLAIN ESTIMATE 比较器
↓
可选检索顾问 (Qdrant + 嵌入)
↓
报告(控制台 | JSON | Markdown | MCP)
```
## 开发
```bash
poetry install
poetry run pytest -k 'not test_detect_version'
poetry run ruff check clickadvisor tests scripts
poetry run python scripts/eval/run_benchmark.py
```
`tests/integration/test_version.py::test_detect_version` 需要在 `localhost:8123` 上具有可用的 ClickHouse HTTP 端点,并具有适当的凭据。