create-dwy 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/prompts/grouped-checkbox.js +223 -0
- package/src/sync.js +61 -39
- package/templates/claude-global/hooks/pre-git-commit-sensitive-check.sh +0 -0
- package/templates/claude-global/rules/{dwy-python-backend.md → Python/dwy-python-backend.md} +43 -3
- package/templates/claude-global/rules/{dwy-python-core.md → Python/dwy-python-core.md} +35 -2
- package/templates/claude-global/skills//345/237/272/347/241/200/345/272/223/dwy-eapi/SKILL.md +226 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/SKILL.md +144 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/create-database-table.md +219 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/crud-operations.md +281 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/data-import.md +271 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/docker-deployment.md +63 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/performance-tuning.md +223 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/pitfalls-and-best-practices.md +352 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/python-api.md +306 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/setup-and-connection.md +143 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/sources.md +46 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/references/sql-batch-compute.md +206 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-cibuildwheel/SKILL.md +354 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-cibuildwheel/references/release-workflow-template.yml +99 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_base.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_capacity.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_db.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_docker.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_env.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_https.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_logs.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_nginx.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_resilience.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_secrets.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_services.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/check_ssh.sh +0 -0
- package/templates/claude-global/skills/{dwy-deploy-audit → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit}/scripts/run_all.sh +0 -0
- package/templates/claude-global/skills/{dwy-docker → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-docker}/scripts/query_dockerhub.py +0 -0
- package/templates/claude-global/skills/{dwy-docker → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-docker}/scripts/scan_images.sh +0 -0
- package/templates/claude-global/skills/{dwy-mirror-source → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-mirror-source}/scripts/apply_mirrors.py +0 -0
- package/templates/claude-global/skills/{dwy-mirror-source → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-mirror-source}/scripts/check_mirrors.py +0 -0
- package/templates/claude-global/skills/dwy-dolphindb/SKILL.md +0 -98
- package/templates/claude-global/skills/dwy-dolphindb/evals/evals.json +0 -67
- package/templates/claude-global/skills/dwy-dolphindb/references/dolphindb-rules.md +0 -441
- package/templates/claude-global/skills/dwy-eapi/SKILL.md +0 -495
- package/templates/claude-global/skills/dwy-eapi/references/health.md +0 -47
- package/templates/claude-global/skills/dwy-eapi/references/logger.md +0 -60
- /package/templates/claude-global/rules/{dwy-android-core.md → Android/dwy-android-core.md} +0 -0
- /package/templates/claude-global/rules/{dwy-flutter-core.md → Flutter/dwy-flutter-core.md} +0 -0
- /package/templates/claude-global/rules/{dwy-flutter-network.md → Flutter/dwy-flutter-network.md} +0 -0
- /package/templates/claude-global/rules/{dwy-flutter-router.md → Flutter/dwy-flutter-router.md} +0 -0
- /package/templates/claude-global/rules/{dwy-flutter-testing.md → Flutter/dwy-flutter-testing.md} +0 -0
- /package/templates/claude-global/rules/{dwy-python-testing.md → Python/dwy-python-testing.md} +0 -0
- /package/templates/claude-global/rules/{dwy-vue-core.md → Vue/dwy-vue-core.md} +0 -0
- /package/templates/claude-global/rules/{dwy-vue-pinia.md → Vue/dwy-vue-pinia.md} +0 -0
- /package/templates/claude-global/rules/{dwy-vue-testing.md → Vue/dwy-vue-testing.md} +0 -0
- /package/templates/claude-global/rules/{dwy-tdd-development.md → /345/274/200/345/217/221/346/265/201/347/250/213/dwy-tdd-development.md"} +0 -0
- /package/templates/claude-global/rules/{dwy-db-migration.md → /346/225/260/346/215/256/345/272/223/dwy-db-migration.md"} +0 -0
- /package/templates/claude-global/rules/{dwy-postgres.md → /346/225/260/346/215/256/345/272/223/dwy-postgres.md"} +0 -0
- /package/templates/claude-global/rules/{dwy-redis.md → /346/225/260/346/215/256/345/272/223/dwy-redis.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-eapi/references/tasks-integration-guide.md → /345/237/272/347/241/200/345/272/223/dwy-eapi/references/tasks-integration-guide.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-ekit/SKILL.md → /345/237/272/347/241/200/345/272/223/dwy-ekit/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-eui/SKILL.md → /345/237/272/347/241/200/345/272/223/dwy-eui/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-eui/references/eui-design-guide.md → /345/237/272/347/241/200/345/272/223/dwy-eui/references/eui-design-guide.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-eui/references/eui-integration-guide.md → /345/237/272/347/241/200/345/272/223/dwy-eui/references/eui-integration-guide.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-eui/references/eui-landing-design-guide.md → /345/237/272/347/241/200/345/272/223/dwy-eui/references/eui-landing-design-guide.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/SKILL.md → /345/256/211/345/205/250/dwy-pentest/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/.python-version → /345/256/211/345/205/250/dwy-pentest/scripts/.python-version"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/__init__.py → /345/256/211/345/205/250/dwy-pentest/scripts/lib/__init__.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/__pycache__/__init__.cpython-311.pyc → /345/256/211/345/205/250/dwy-pentest/scripts/lib/__pycache__/__init__.cpython-311.pyc"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/__pycache__/config.cpython-311.pyc → /345/256/211/345/205/250/dwy-pentest/scripts/lib/__pycache__/config.cpython-311.pyc"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/__pycache__/executor.cpython-311.pyc → /345/256/211/345/205/250/dwy-pentest/scripts/lib/__pycache__/executor.cpython-311.pyc"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/__pycache__/severity.cpython-311.pyc → /345/256/211/345/205/250/dwy-pentest/scripts/lib/__pycache__/severity.cpython-311.pyc"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/__pycache__/validator.cpython-311.pyc → /345/256/211/345/205/250/dwy-pentest/scripts/lib/__pycache__/validator.cpython-311.pyc"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/config.py → /345/256/211/345/205/250/dwy-pentest/scripts/lib/config.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/executor.py → /345/256/211/345/205/250/dwy-pentest/scripts/lib/executor.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/severity.py → /345/256/211/345/205/250/dwy-pentest/scripts/lib/severity.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/lib/validator.py → /345/256/211/345/205/250/dwy-pentest/scripts/lib/validator.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/pentest_auth.py → /345/256/211/345/205/250/dwy-pentest/scripts/pentest_auth.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/pentest_recon.py → /345/256/211/345/205/250/dwy-pentest/scripts/pentest_recon.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/pentest_report.py → /345/256/211/345/205/250/dwy-pentest/scripts/pentest_report.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/pentest_scan.py → /345/256/211/345/205/250/dwy-pentest/scripts/pentest_scan.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/pentest_ssl.py → /345/256/211/345/205/250/dwy-pentest/scripts/pentest_ssl.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/pentest_vuln.py → /345/256/211/345/205/250/dwy-pentest/scripts/pentest_vuln.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/pentest_web.py → /345/256/211/345/205/250/dwy-pentest/scripts/pentest_web.py"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/pyproject.toml → /345/256/211/345/205/250/dwy-pentest/scripts/pyproject.toml"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/setup_tools.sh → /345/256/211/345/205/250/dwy-pentest/scripts/setup_tools.sh"} +0 -0
- /package/templates/claude-global/skills/{dwy-pentest/scripts/uv.lock → /345/256/211/345/205/250/dwy-pentest/scripts/uv.lock"} +0 -0
- /package/templates/claude-global/skills/{dwy-dev-qa/SKILL.md → /345/274/200/345/217/221/346/265/201/347/250/213/dwy-dev-qa/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-git-commit/SKILL.md → /345/274/200/345/217/221/346/265/201/347/250/213/dwy-git-commit/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-fullstack-scaffold/SKILL.md → /350/204/232/346/211/213/346/236/266/dwy-fullstack-scaffold/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-tech-stack/SKILL.md → /350/204/232/346/211/213/346/236/266/dwy-tech-stack/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-deploy-audit/SKILL.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-deploy-audit/references/checks-data.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/references/checks-data.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-deploy-audit/references/checks-network.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/references/checks-network.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-deploy-audit/references/checks-runtime.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/references/checks-runtime.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-docker/SKILL.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-docker/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-docker/references/ask-templates.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-docker/references/ask-templates.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-docker/references/templates.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-docker/references/templates.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-docker/references/version-rules.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-docker/references/version-rules.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-mirror-source/SKILL.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-mirror-source/SKILL.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-mirror-source/references/dockerfile-snippets.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-mirror-source/references/dockerfile-snippets.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-mirror-source/references/mirror-providers.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-mirror-source/references/mirror-providers.md"} +0 -0
- /package/templates/claude-global/skills/{dwy-mirror-source/scripts/__pycache__/check_mirrors.cpython-313.pyc → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-mirror-source/scripts/__pycache__/check_mirrors.cpython-313.pyc"} +0 -0
- /package/templates/claude-global/skills/{dwy-publish/SKILL.md → /350/277/220/347/273/264/345/217/221/345/270/203/dwy-publish/SKILL.md"} +0 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# 性能排查与调优
|
|
2
|
+
|
|
3
|
+
## 社区版 2核8G 资源预算(**死守**)
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
总内存 8 GB
|
|
7
|
+
├── OS + DDB 自身 ~1 GB
|
|
8
|
+
├── chunkCache + 索引 ~1.5 GB
|
|
9
|
+
├── 4 个 worker 缓冲 ~1.5 GB
|
|
10
|
+
├── 留给单查询的预算 ≤ 2 GB ← 任何 SELECT/计算别超
|
|
11
|
+
└── 安全冗余 ~2 GB
|
|
12
|
+
|
|
13
|
+
CPU 2 核 → worker 4 → 实际并发能力 ≤ 4
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**查询前估算**:
|
|
17
|
+
|
|
18
|
+
```dolphindb
|
|
19
|
+
// 估这个查询要多大内存
|
|
20
|
+
select count(*) * 1000 / 1024 / 1024 as mb_estimate // 假设每行 1KB
|
|
21
|
+
from loadTable("dfs://x", "t")
|
|
22
|
+
where TradeDate between 2024.01.01 and 2024.01.05
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
行数 × 列宽 > 2GB → 必须分批 / mr / 分页。
|
|
26
|
+
|
|
27
|
+
## 5 分钟排查清单
|
|
28
|
+
|
|
29
|
+
按顺序执行:
|
|
30
|
+
|
|
31
|
+
```dolphindb
|
|
32
|
+
// 1. 集群整体(看 CPU/内存/磁盘)
|
|
33
|
+
getClusterPerf()
|
|
34
|
+
|
|
35
|
+
// 2. 所有节点的同步作业(用户正在跑的查询)
|
|
36
|
+
pnodeRun(getConsoleJobs)
|
|
37
|
+
|
|
38
|
+
// 3. 最近 20 个异步作业
|
|
39
|
+
getRecentJobs(20)
|
|
40
|
+
|
|
41
|
+
// 4. 当前 session 内存
|
|
42
|
+
getSessionMemoryStat()
|
|
43
|
+
|
|
44
|
+
// 5. 整机内存细节
|
|
45
|
+
getMemoryStat()
|
|
46
|
+
|
|
47
|
+
// 6. 磁盘 IO
|
|
48
|
+
getDiskIOStat()
|
|
49
|
+
|
|
50
|
+
// 7. 看慢查询用了哪些分区
|
|
51
|
+
select [HINT_EXPLAIN] * from loadTable(dbName,tbName) where 你的条件
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 监控命令速查
|
|
55
|
+
|
|
56
|
+
| 命令 | 用途 | 输出关键列 |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `getClusterPerf()` | 集群整体 | name, mode, host, port, memUsed, cpuUsage |
|
|
59
|
+
| `getPerf()` | 单节点 | 同上单节点版 |
|
|
60
|
+
| `getConsoleJobs()` | 同步作业(用户当前查询) | rootJobId, sessionId, userId, startTime, jobDesc |
|
|
61
|
+
| `pnodeRun(getConsoleJobs)` | **所有节点**的同步作业 | 同上 |
|
|
62
|
+
| `getRecentJobs(n)` | 最近 n 个异步作业 | jobId, status, startTime, endTime, errorMsg |
|
|
63
|
+
| `getJobStatus(jobId)` | 单个异步作业状态 | status, progress |
|
|
64
|
+
| `getJobMessage(jobId)` | 异步作业日志 | print 出的内容 |
|
|
65
|
+
| `getJobReturn(jobId)` | 异步作业返回值 | 计算结果 |
|
|
66
|
+
| `getSessionMemoryStat()` | 各 session 内存 | sessionId, memSize, lastActiveTime |
|
|
67
|
+
| `getMemoryStat()` | 节点内存细节 | shared array memory, chunk cache 等 |
|
|
68
|
+
| `getDiskIOStat()` | 磁盘 IO | read/write speed, IOPS |
|
|
69
|
+
| `getTableDiskUsage(db, tb)` | 表磁盘占用 | size per partition |
|
|
70
|
+
| `getClusterChunksStatus()` | 分区分布 | chunkPath, state, version |
|
|
71
|
+
| `getAllChunks()` | 所有 chunk | 同上详细版 |
|
|
72
|
+
|
|
73
|
+
## 杀作业
|
|
74
|
+
|
|
75
|
+
```dolphindb
|
|
76
|
+
// 同步作业(getConsoleJobs 找到 rootJobId)
|
|
77
|
+
cancelConsoleJob(`xxxxxxxx)
|
|
78
|
+
|
|
79
|
+
// 异步作业(getRecentJobs 找到 jobId)
|
|
80
|
+
cancelJob(`yyyyyyyy)
|
|
81
|
+
|
|
82
|
+
// 取消是设置标志,不立即生效,再过几秒看是否结束
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 慢查询排查流程
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
1. 加 [HINT_EXPLAIN] 看是否分区剪枝
|
|
89
|
+
├── 没剪枝 → 改 WHERE(见 crud-operations.md)
|
|
90
|
+
└── 剪枝了但还慢 ↓
|
|
91
|
+
2. 查 getConsoleJobs:是不是被其他作业抢资源
|
|
92
|
+
├── 是 → 排队 / 降优先级
|
|
93
|
+
└── 否 ↓
|
|
94
|
+
3. 查 getDiskIOStat:是不是磁盘瓶颈
|
|
95
|
+
├── 是 → 减少扫描分区 / 升 SSD
|
|
96
|
+
└── 否 ↓
|
|
97
|
+
4. 查 getSessionMemoryStat:内存是否爆
|
|
98
|
+
├── 是 → 拆批 / mr / fetchSize 分页
|
|
99
|
+
└── 否 ↓
|
|
100
|
+
5. 查 schema:sortColumns 是否覆盖 WHERE 条件
|
|
101
|
+
└── 不覆盖 → 重建表(TSDB sortColumns 不能改)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 常见性能问题
|
|
105
|
+
|
|
106
|
+
### 问题 1:查询返回慢
|
|
107
|
+
|
|
108
|
+
**症状**:`select` 跑 30 秒+ 才返回。
|
|
109
|
+
|
|
110
|
+
**排查**:
|
|
111
|
+
```dolphindb
|
|
112
|
+
select [HINT_EXPLAIN] * from t where ...
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
输出里看 `PartitionInfo`:
|
|
116
|
+
- 扫描分区数 ≈ 总分区数 → 没剪枝
|
|
117
|
+
- 扫描分区数 = 预期 → 看 `scannedRows`
|
|
118
|
+
|
|
119
|
+
**修复**:
|
|
120
|
+
- 没剪枝 → WHERE 用分区列直接等于/between
|
|
121
|
+
- 数据量太大 → 服务端先聚合再返回(`group by` 而不是 `select *`)
|
|
122
|
+
|
|
123
|
+
### 问题 2:写入慢
|
|
124
|
+
|
|
125
|
+
**症状**:`tableInsert` 1 万行要 10 秒。
|
|
126
|
+
|
|
127
|
+
**排查**:
|
|
128
|
+
```dolphindb
|
|
129
|
+
pnodeRun(getConsoleJobs) // 是否多个写并发抢同一分区
|
|
130
|
+
getDiskIOStat() // 磁盘是否饱和
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**修复**:
|
|
134
|
+
- 多 worker 抢同一分区 → 改成 `PartitionedTableAppender` 按分区列分发
|
|
135
|
+
- 单连接 → 用 `DBConnectionPool` size 3
|
|
136
|
+
- 索引膨胀(TSDB) → 看 `getTableDiskUsage`,索引大于数据 = sortColumns 选错了
|
|
137
|
+
|
|
138
|
+
### 问题 3:OOM (Out of memory)
|
|
139
|
+
|
|
140
|
+
**症状**:报 `Out of memory`,节点重启。
|
|
141
|
+
|
|
142
|
+
**根因排查**:
|
|
143
|
+
```dolphindb
|
|
144
|
+
getMemoryStat() // 看哪部分占内存
|
|
145
|
+
getSessionMemoryStat() // 哪个 session 持有大对象
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**常见原因 + 修复**:
|
|
149
|
+
| 原因 | 修复 |
|
|
150
|
+
|---|---|
|
|
151
|
+
| 单查询拉太多数据 | Python 端 `fetchSize=8192` 分段拉 |
|
|
152
|
+
| 服务端 `context by` 大表 | 改 `mr` 按分区计算 |
|
|
153
|
+
| 客户端 `df = s.run("select *")` | 改 `group by` 服务端聚合 |
|
|
154
|
+
| 大批量 import 没拆 | 切成 100MB 一批 |
|
|
155
|
+
| `pivot by` 产生超大矩阵 | 先过滤再 pivot |
|
|
156
|
+
|
|
157
|
+
### 问题 4:节点卡死 / 无响应
|
|
158
|
+
|
|
159
|
+
**应急**:
|
|
160
|
+
1. 另起 session(用 controller 端口 8848)
|
|
161
|
+
2. `getClusterPerf()` 看哪个节点 mem 100%
|
|
162
|
+
3. `rpc("nodeX", getConsoleJobs)` 查那个节点的作业
|
|
163
|
+
4. `rpc("nodeX", cancelConsoleJob, jobId)` 杀掉
|
|
164
|
+
5. 如果完全卡死 → 安全重启该节点(不是 kill -9)
|
|
165
|
+
|
|
166
|
+
**预防**:startup 脚本里加:
|
|
167
|
+
```dolphindb
|
|
168
|
+
// 自动清理超时 session
|
|
169
|
+
addJob("session_cleanup", "kill idle sessions", {def(){
|
|
170
|
+
sessions = getSessionMemoryStat()
|
|
171
|
+
idle = select sessionId from sessions where lastActiveTime < now() - 3600*1000
|
|
172
|
+
each(closeSession, idle.sessionId)
|
|
173
|
+
}}, 0, 1, `hour)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 问题 5:磁盘要满了
|
|
177
|
+
|
|
178
|
+
**监控**:
|
|
179
|
+
```dolphindb
|
|
180
|
+
// 各表占用
|
|
181
|
+
select * from getTableDiskUsage(getClusterDFSDatabases()[0])
|
|
182
|
+
|
|
183
|
+
// 整库
|
|
184
|
+
select sum(diskUsage) as totalGB from (
|
|
185
|
+
each(getTableDiskUsage, getClusterDFSDatabases())
|
|
186
|
+
)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**清理**:
|
|
190
|
+
- 旧分区 `dropPartition` 删除(按日期)
|
|
191
|
+
- TSDB 的 redo log 自动清理,但磁盘满会卡写
|
|
192
|
+
- chunk cache 设上限:`chunkCacheEngineMemSize=1` (GB)
|
|
193
|
+
|
|
194
|
+
## 配置调优(社区版 dolphindb.cfg)
|
|
195
|
+
|
|
196
|
+
社区版固定 2核8G,可调的关键参数:
|
|
197
|
+
|
|
198
|
+
| 参数 | 建议值 | 说明 |
|
|
199
|
+
|---|---|---|
|
|
200
|
+
| `maxMemSize` | 6 (GB) | 节点最大内存,留 2GB 给 OS |
|
|
201
|
+
| `workerNum` | 4 | worker 线程数 = CPU 核数 × 2 |
|
|
202
|
+
| `localExecutors` | 3 | 本地并发执行器 |
|
|
203
|
+
| `chunkCacheEngineMemSize` | 1 (GB) | 列缓存,太大挤压查询内存 |
|
|
204
|
+
| `TSDBCacheEngineSize` | 0.5 (GB) | TSDB 写缓存 |
|
|
205
|
+
| `webWorkerNum` | 1 | Web UI 用,留 1 个够 |
|
|
206
|
+
|
|
207
|
+
**修改方式**:编辑配置文件 → 重启集群。或运行时 `setMaxMemSize(...)`(部分参数支持热改)。
|
|
208
|
+
|
|
209
|
+
## 性能基线(参考)
|
|
210
|
+
|
|
211
|
+
| 操作 | 2核8G 社区版 |
|
|
212
|
+
|---|---|
|
|
213
|
+
| 单股单天 tick 点查 | < 100ms |
|
|
214
|
+
| 单股一月 tick 扫描 | 1-3s |
|
|
215
|
+
| 全市场单日聚合(5000股) | 3-10s |
|
|
216
|
+
| K 线合成(1 个月 + 1000 股) | 30-60s |
|
|
217
|
+
| 因子计算(截面 z-score, 1 月) | 10-30s |
|
|
218
|
+
| Python 拉 100 万行 → DataFrame | 2-5s |
|
|
219
|
+
| PartitionedTableAppender 写入 | 200-400 万行/s |
|
|
220
|
+
|
|
221
|
+
超过基线 2-3x 必须排查(剪枝、索引、并发)。
|
|
222
|
+
|
|
223
|
+
跨引用:建表选型 → [[create-database-table]],查询写法 → [[crud-operations]]。
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# 反模式与最佳实践
|
|
2
|
+
|
|
3
|
+
## 类型陷阱
|
|
4
|
+
|
|
5
|
+
### 1. DATETIME 2038 溢出
|
|
6
|
+
|
|
7
|
+
```dolphindb
|
|
8
|
+
// ❌ 32 位 int,范围 [1901.12.13T20:45:53, 2038.01.19T03:14:07]
|
|
9
|
+
// 超出 → 整数溢出 → 显示 1970 异常
|
|
10
|
+
t = table(1:0, `ts, [DATETIME])
|
|
11
|
+
|
|
12
|
+
// ✅ 全用 TIMESTAMP(毫秒精度,64 位 long)
|
|
13
|
+
t = table(1:0, `ts, [TIMESTAMP])
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**铁律**:新表别用 `DATETIME`,统一 `TIMESTAMP`。
|
|
17
|
+
|
|
18
|
+
### 2. FLOAT/DOUBLE 精度(金融场景禁用)
|
|
19
|
+
|
|
20
|
+
```dolphindb
|
|
21
|
+
0.1 + 0.2 == 0.3 // false! (DOUBLE 精度问题)
|
|
22
|
+
eqFloat(0.1 + 0.2, 0.3) // true(专用比较函数)
|
|
23
|
+
|
|
24
|
+
// ❌ 价格用 DOUBLE
|
|
25
|
+
price DOUBLE
|
|
26
|
+
|
|
27
|
+
// ✅ 用 DECIMAL
|
|
28
|
+
price DECIMAL64(6) // 6 位小数,精确到 0.000001
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
DECIMAL 比 DOUBLE 慢 ~30%,但金融场景必须用。
|
|
32
|
+
|
|
33
|
+
### 3. CHAR 不自动转 SYMBOL
|
|
34
|
+
|
|
35
|
+
```dolphindb
|
|
36
|
+
// ❌ CHAR 直接 append 到 SYMBOL 列
|
|
37
|
+
c = char(65) // 'A'
|
|
38
|
+
symbolVec.append!(c) // 报错或乱码
|
|
39
|
+
|
|
40
|
+
// ✅ 显式转 STRING
|
|
41
|
+
symbolVec.append!(c.string()) // STRING 会自动转 SYMBOL
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 4. 除法运算 `/` 和 `\` 反过来
|
|
45
|
+
|
|
46
|
+
```dolphindb
|
|
47
|
+
100 / 3 // 33(取整)
|
|
48
|
+
100 \ 3 // 33.333333...(浮点)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
DDB 和 Python/SQL **相反**!老手都踩过。要小数结果用 `\`。
|
|
52
|
+
|
|
53
|
+
### 5. SYMBOL ≤255 字节 / STRING 64KB / BLOB 64MB 静默截断(**1.30.23 / 2.00.11 起**)
|
|
54
|
+
|
|
55
|
+
| 类型 | 上限 | 超限行为 |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `SYMBOL` | **≤ 255 字节** | **整批 append 直接抛异常**,写入失败 |
|
|
58
|
+
| `STRING` | < 64 KB | 静默截断到 65535 字节 |
|
|
59
|
+
| `BLOB` | < 64 MB | 静默截断到 67108863 字节 |
|
|
60
|
+
|
|
61
|
+
**SYMBOL 校验是写入前必做**,否则整批失败:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
MAX_SYMBOL_BYTES = 255
|
|
65
|
+
|
|
66
|
+
# UTF-8 字节数 = .encode() 后长度(中文 1 字 ≈ 3 字节)
|
|
67
|
+
oversize = batch_df["order_book_id"].str.encode("utf-8").str.len() > MAX_SYMBOL_BYTES
|
|
68
|
+
if oversize.any():
|
|
69
|
+
raise ValueError(f"SYMBOL 列有 {oversize.sum()} 行超过 255 字节")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**STRING/BLOB 截断不可逆**:写入前必须做长度断言,事后无法恢复原数据。
|
|
73
|
+
|
|
74
|
+
类型选择:
|
|
75
|
+
- 短编码(股票代码、因子名)→ `SYMBOL`,但校验 ≤255 字节
|
|
76
|
+
- 中等文本(备注、描述)→ `STRING`,应用层卡 64KB
|
|
77
|
+
- 大文本/二进制(JSON、文件)→ `BLOB`,应用层卡 64MB
|
|
78
|
+
|
|
79
|
+
### 6. NULL / NaN / 空字符串 区别
|
|
80
|
+
|
|
81
|
+
| 值 | 类型 | 表达 |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| NULL | VOID / 类型化 | `NULL`, `int()`, `00i` |
|
|
84
|
+
| NaN | FLOAT/DOUBLE | 无效数值结果 |
|
|
85
|
+
| 空字符串 | STRING | `""` |
|
|
86
|
+
|
|
87
|
+
```dolphindb
|
|
88
|
+
isNull(NULL) // true
|
|
89
|
+
isNull(NaN) // true
|
|
90
|
+
isNull("") // false! 空串不是 NULL
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
填空用:`nullFill(x, 0)`、`ffill(x)`(前值填充)。
|
|
94
|
+
|
|
95
|
+
## DDB 脚本语法陷阱
|
|
96
|
+
|
|
97
|
+
### 1. backtick 列名必须单行
|
|
98
|
+
|
|
99
|
+
```dolphindb
|
|
100
|
+
// ❌ 多行 backtick 列名 → 语法错误
|
|
101
|
+
schema = table(1:0,
|
|
102
|
+
`col1`col2
|
|
103
|
+
`col3`col4,
|
|
104
|
+
[INT, INT, INT, INT])
|
|
105
|
+
|
|
106
|
+
// ✅ 单行定义;多列必须先变量化
|
|
107
|
+
colNames = `col1`col2`col3`col4
|
|
108
|
+
colTypes = [INT, INT, INT, INT]
|
|
109
|
+
schema = table(1:0, colNames, colTypes)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 2. 多值 SYMBOL 拼接
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
# ✅ DDB 语法:`v1`v2`v3 是 SYMBOL 向量字面量
|
|
116
|
+
symbols = ["000001.XSHE", "000002.XSHE"]
|
|
117
|
+
symbols_str = "`" + "`".join(symbols)
|
|
118
|
+
script = f"... where order_book_id in [{symbols_str}]"
|
|
119
|
+
# 生成:where order_book_id in [`000001.XSHE`000002.XSHE]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 3. 脚本拼接用 `;\n` 分隔
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
# ✅ 多语句之间必须分号 + 换行
|
|
126
|
+
script = (
|
|
127
|
+
f'tickData = select * from loadTable("dfs://x","t") where {flt};\n'
|
|
128
|
+
f'{user_script};\n'
|
|
129
|
+
f'exec count(*) from result'
|
|
130
|
+
)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## SQL 陷阱
|
|
134
|
+
|
|
135
|
+
### 1. append! 不检查列名
|
|
136
|
+
|
|
137
|
+
```dolphindb
|
|
138
|
+
// 目标表:t(a INT, b DOUBLE)
|
|
139
|
+
src = table(1.5 as b, 1 as a)
|
|
140
|
+
t.append!(src) // 不报错,但 a 列拿到 1.5(被截断为 1),b 拿到 1.0
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**铁律**:append 前必须 `reorderColumns!`:
|
|
144
|
+
```dolphindb
|
|
145
|
+
src.reorderColumns!(t.schema().colDefs.name)
|
|
146
|
+
t.append!(src)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 2. WHERE 包裹分区列函数 → 不剪枝
|
|
150
|
+
|
|
151
|
+
```dolphindb
|
|
152
|
+
// ❌ 函数包裹了分区列
|
|
153
|
+
where year(TradeDate) = 2024
|
|
154
|
+
where temporalAdd(TradeDate, 1, 'd') > 2024.01.03
|
|
155
|
+
|
|
156
|
+
// ✅ 直接比较
|
|
157
|
+
where TradeDate >= 2024.01.01 and TradeDate < 2025.01.01
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### 3. 不触发分区剪枝的 WHERE(**慢查询头号原因**)
|
|
161
|
+
|
|
162
|
+
```dolphindb
|
|
163
|
+
// ❌ 链式比较 DDB 不识别
|
|
164
|
+
where 2024.01.01 <= TradeDate <= 2024.01.05
|
|
165
|
+
|
|
166
|
+
// ❌ 列被函数包裹
|
|
167
|
+
where year(TradeDate) = 2024
|
|
168
|
+
where temporalAdd(TradeDate, 1, 'd') > 2024.01.03
|
|
169
|
+
|
|
170
|
+
// ❌ 列上做运算
|
|
171
|
+
where TradeDate + 1 = 2024.01.04
|
|
172
|
+
|
|
173
|
+
// ✅ 全部改成直接比较 / between / in
|
|
174
|
+
where TradeDate between 2024.01.01 and 2024.01.05
|
|
175
|
+
where TradeDate >= 2024.01.01 and TradeDate <= 2024.01.05
|
|
176
|
+
where TradeDate in [2024.01.03, 2024.01.04]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**验证是否剪枝**:`select [HINT_EXPLAIN] * from t where ...`,看输出的 `PartitionInfo` 扫描数。详见 [[crud-operations]] 「分区剪枝」一节。
|
|
180
|
+
|
|
181
|
+
### 4. group by 必须搭配聚合
|
|
182
|
+
|
|
183
|
+
```dolphindb
|
|
184
|
+
// ❌ select 含非聚合列且不在 group by 里
|
|
185
|
+
select TradeTime, SecurityID, sum(vol) from t group by SecurityID
|
|
186
|
+
|
|
187
|
+
// ✅
|
|
188
|
+
select SecurityID, sum(vol) from t group by SecurityID
|
|
189
|
+
// 或保留所有行用 context by
|
|
190
|
+
select TradeTime, SecurityID, sum(vol) from t context by SecurityID
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### 5. select 出来一定是表
|
|
194
|
+
|
|
195
|
+
```dolphindb
|
|
196
|
+
// 想要标量
|
|
197
|
+
x = select avg(price) from t // 这是只有 1 行 1 列的 table,不是数字
|
|
198
|
+
|
|
199
|
+
// 取标量
|
|
200
|
+
x = exec avg(price) from t // exec 才返回标量/向量
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## 库表设计反模式
|
|
204
|
+
|
|
205
|
+
### 1. TSDB sortColumns 用唯一列
|
|
206
|
+
|
|
207
|
+
```dolphindb
|
|
208
|
+
// ❌ orderId 是唯一的 → 索引膨胀
|
|
209
|
+
sortColumns = ["orderId"]
|
|
210
|
+
|
|
211
|
+
// ✅ 业务键 + 时间
|
|
212
|
+
sortColumns = ["SecurityID", "TradeTime"]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 2. VALUE 分区预建大量空分区
|
|
216
|
+
|
|
217
|
+
```dolphindb
|
|
218
|
+
// ❌ 一次建 10 年空分区,元数据爆炸
|
|
219
|
+
partitioned by VALUE(2020.01.01..2030.12.31)
|
|
220
|
+
|
|
221
|
+
// ✅ 建初始几天,VALUE 会自动扩展
|
|
222
|
+
partitioned by VALUE(2024.01.01..2024.01.07)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 3. 分区粒度过细
|
|
226
|
+
|
|
227
|
+
```dolphindb
|
|
228
|
+
// ❌ 按分钟分区,一天 240 个分区,10 天 2400 个
|
|
229
|
+
partitioned by VALUE(09:30:00..15:00:00)
|
|
230
|
+
|
|
231
|
+
// ✅ 日级分区已足够并行
|
|
232
|
+
partitioned by VALUE(2024.01.01..2024.01.07)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
目标:单分区压缩后 **TSDB 400MB-1GB / OLAP 100MB-300MB**。
|
|
236
|
+
|
|
237
|
+
### 4. 主键、唯一索引、自增列
|
|
238
|
+
|
|
239
|
+
DDB 全部**不支持**。靠业务保证唯一性,用 `upsert!(keyColNames=...)` 做去重。
|
|
240
|
+
|
|
241
|
+
### 5. 改字段顺序、删分区列、改分区列类型
|
|
242
|
+
|
|
243
|
+
全部**不支持**。建表前用一周数据 dry-run。
|
|
244
|
+
|
|
245
|
+
## 写入反模式
|
|
246
|
+
|
|
247
|
+
### 1. 多 worker 并发写同一分区
|
|
248
|
+
|
|
249
|
+
```dolphindb
|
|
250
|
+
// ❌ parallel=true 写同一 DFS 表
|
|
251
|
+
mr(ds, tableInsert{loadTable(dbName,tb)}, parallel=true)
|
|
252
|
+
|
|
253
|
+
// ✅ 写入 mr 必须 parallel=false
|
|
254
|
+
mr(ds, tableInsert{loadTable(dbName,tb)}, parallel=false)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
要并发写 → 用 `PartitionedTableAppender` 按分区列分发。
|
|
258
|
+
|
|
259
|
+
### 2. for 循环逐行 insert
|
|
260
|
+
|
|
261
|
+
```dolphindb
|
|
262
|
+
// ❌ 1 万行循环 = 1 万次事务
|
|
263
|
+
for(row in rows){
|
|
264
|
+
insert into t values(row[0], row[1], row[2])
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// ✅ 批量
|
|
268
|
+
t.tableInsert(rows)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### 3. 没显式关闭 session / pool
|
|
272
|
+
|
|
273
|
+
Python 长服务必用 try/finally 或 context manager。512 连接很快就吃满。
|
|
274
|
+
|
|
275
|
+
## 运维反模式(**会丢数据**)
|
|
276
|
+
|
|
277
|
+
### 1. 直接拷贝底层文件做迁移
|
|
278
|
+
|
|
279
|
+
❌ 不要 `cp -r /dolphindb/data /backup/`
|
|
280
|
+
✅ 用 `backup()` 和 `restore()` 函数
|
|
281
|
+
|
|
282
|
+
### 2. 改 hostname / IP 不停服
|
|
283
|
+
|
|
284
|
+
集群元数据里有 host 引用,改了直接起不来。必须先停集群 → 改配置 → 起。
|
|
285
|
+
|
|
286
|
+
### 3. 删 redo log / chunk meta 目录
|
|
287
|
+
|
|
288
|
+
`dfsMetaDir / chunkMetaDir / TSDBRedoLogDir / persistenceDir` 这些目录的文件**绝对不能删**,删了数据全废。
|
|
289
|
+
|
|
290
|
+
### 4. kill -9 节点
|
|
291
|
+
|
|
292
|
+
会丢未刷盘的事务。用 `stopDataNode(`name)` 或 Web 安全关机。
|
|
293
|
+
|
|
294
|
+
### 5. 磁盘 100% 后再处理
|
|
295
|
+
|
|
296
|
+
磁盘满 → 写入卡 → 元数据可能损坏。监控阈值设 80%。
|
|
297
|
+
|
|
298
|
+
## 模块/脚本管理
|
|
299
|
+
|
|
300
|
+
### 1. 改了 module 不重连
|
|
301
|
+
|
|
302
|
+
```dolphindb
|
|
303
|
+
clearCachedModules() // 清缓存
|
|
304
|
+
use mymodule // 重新加载
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
否则旧版本还在 session 缓存里。
|
|
308
|
+
|
|
309
|
+
### 2. 重型脚本不用 submitJob
|
|
310
|
+
|
|
311
|
+
同步执行 = 客户端阻塞、keepAlive 超时断连。
|
|
312
|
+
|
|
313
|
+
```dolphindb
|
|
314
|
+
// ❌ 客户端 hang
|
|
315
|
+
re = mr(ds, calcHeavy, , unionAll, false)
|
|
316
|
+
|
|
317
|
+
// ✅ 异步提交,去 getRecentJobs 看进度
|
|
318
|
+
jobId = submitJob("calcHeavy", "monthly calc", {def(){
|
|
319
|
+
re = mr(ds, calcHeavy, , unionAll, false)
|
|
320
|
+
loadTable(dbName, "result").tableInsert(re)
|
|
321
|
+
}})
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## 字符编码
|
|
325
|
+
|
|
326
|
+
```dolphindb
|
|
327
|
+
// CSV 是 GBK,DDB 默认 UTF-8 → 乱码
|
|
328
|
+
loadTextEx(..., schema=schema, encoding="GBK")
|
|
329
|
+
|
|
330
|
+
// 字符串编码转换
|
|
331
|
+
str.convertEncode("GBK", "UTF-8")
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Best Practice 速查
|
|
335
|
+
|
|
336
|
+
| 场景 | 做法 |
|
|
337
|
+
|---|---|
|
|
338
|
+
| 时间列 | 一律 `TIMESTAMP`(不要 DATETIME) |
|
|
339
|
+
| 价格金额 | `DECIMAL64(6)` 或 `DECIMAL32(3)` |
|
|
340
|
+
| 股票代码 | `SYMBOL` |
|
|
341
|
+
| 10 档行情 | 数组向量 `DOUBLE[]` 一列 |
|
|
342
|
+
| 单调列压缩 | `compress="delta"` |
|
|
343
|
+
| 删数据 | `dropPartition` 不要 `delete from` |
|
|
344
|
+
| 改数据 | OLAP 删分区重写,TSDB `update` 或 `upsert!` |
|
|
345
|
+
| 写并发 | `PartitionedTableAppender` + pool size 3 |
|
|
346
|
+
| 大查询 | 服务端聚合 + Python `fetchSize` |
|
|
347
|
+
| 重计算 | `submitJob` 异步 |
|
|
348
|
+
| 监控 | `getClusterPerf` + `pnodeRun(getConsoleJobs)` |
|
|
349
|
+
| 备份 | `backup()` / `restore()` 不要拷文件 |
|
|
350
|
+
| 关连接 | try/finally 或 context manager |
|
|
351
|
+
|
|
352
|
+
跨引用:建表选型 → [[create-database-table]],调优 → [[performance-tuning]]。
|