1
1
---
2
- title : 查询优化 (Query Optimization)
2
+ title : 查询优化
3
3
---
4
4
5
- 通过性能分析工具、执行计划 (Execution Plan) 和优化技术来分析和提升查询性能 。
5
+ 使用性能分析工具、执行计划和优化技术来分析和提升查询性能 。
6
6
7
7
## 性能分析工具
8
8
9
- ### [ 查询概况 (Query Profile) ] ( ./query-profile.md )
9
+ ### [ 查询分析 ] ( ./query-profile.md )
10
10
Databend Cloud 中的可视化执行计划分析
11
- - ** 访问 ** :监控 → SQL 历史 → 查询概况 (Query Profile) 选项卡
12
- - ** 展示 ** :执行节点、耗时、资源使用情况
11
+ - ** 访问路径 ** :监控 → SQL 历史 → 查询分析标签页
12
+ - ** 展示内容 ** :执行节点、耗时、资源使用情况
13
13
- ** 用途** :识别瓶颈、理解查询执行过程
14
14
15
- ### [ 查询哈希 (Query Hash) ] ( ./query-hash.md )
15
+ ### [ 查询哈希] ( ./query-hash.md )
16
16
用于性能追踪的唯一查询指纹
17
17
``` sql
18
18
-- 获取查询指纹
@@ -21,7 +21,7 @@ SELECT query_hash('SELECT * FROM table WHERE id = ?');
21
21
22
22
## 查询优化基础
23
23
24
- ### 执行计划分析 (Execution Plan Analysis)
24
+ ### 执行计划分析
25
25
``` sql
26
26
-- 查看查询执行计划
27
27
EXPLAIN SELECT * FROM orders o
@@ -30,12 +30,12 @@ WHERE o.order_date >= '2023-01-01';
30
30
```
31
31
32
32
** 关注点:**
33
- - ** 表扫描 (Table Scans) ** vs ** 索引使用 (Index Usage) **
34
- - ** 连接算法 (Join Algorithms) ** (哈希、合并、嵌套循环)
35
- - ** 过滤器下推 (Filter Pushdown) ** 的有效性
36
- - ** 资源消耗 (Resource Consumption) ** 估算
33
+ - ** 表扫描** vs ** 索引使用**
34
+ - ** 连接算法** (哈希、合并、嵌套循环)
35
+ - ** 过滤下推 ** 效果
36
+ - ** 资源消耗** 估算
37
37
38
- ### 索引策略 (Index Strategy)
38
+ ### 索引策略
39
39
``` sql
40
40
-- 为常见查询模式创建索引
41
41
CREATE INDEX idx_orders_date ON orders(order_date);
@@ -44,13 +44,13 @@ CREATE INDEX idx_orders_customer ON orders(customer_id);
44
44
45
45
** 索引指南:**
46
46
- 为 WHERE 子句中的列创建索引
47
- - 为连接 ( JOIN) 两侧的列创建索引
48
- - 考虑为多列过滤器创建复合索引 (Composite Index)
47
+ - 为 JOIN 两侧的列创建索引
48
+ - 为多列过滤条件考虑复合索引
49
49
- 监控索引使用统计信息
50
50
51
- ## 性能优化技巧
51
+ ## 性能优化技术
52
52
53
- ### 查询重写 (Query Rewriting)
53
+ ### 查询重写
54
54
``` sql
55
55
-- ❌ 低效:对列使用函数导致无法使用索引
56
56
SELECT * FROM orders WHERE YEAR(order_date) = 2023 ;
@@ -61,22 +61,22 @@ WHERE order_date >= '2023-01-01'
61
61
AND order_date < ' 2024-01-01' ;
62
62
```
63
63
64
- ### 过滤器下推 (Filter Pushdown)
64
+ ### 过滤下推
65
65
``` sql
66
- -- ❌ 在连接后过滤
66
+ -- ❌ 连接后过滤
67
67
SELECT * FROM (
68
68
SELECT o.* , c .name
69
69
FROM orders o JOIN customers c ON o .customer_id = c .id
70
70
) WHERE order_date >= ' 2023-01-01' ;
71
71
72
- -- ✅ 在连接前过滤
72
+ -- ✅ 连接前过滤
73
73
SELECT o.* , c .name
74
74
FROM orders o
75
75
JOIN customers c ON o .customer_id = c .id
76
76
WHERE o .order_date >= ' 2023-01-01' ;
77
77
```
78
78
79
- ### 聚合优化 (Aggregation Optimization)
79
+ ### 聚合优化
80
80
``` sql
81
81
-- 使用合适的 GROUP BY 扩展
82
82
SELECT
@@ -95,43 +95,43 @@ GROUP BY CUBE(region, product_category);
95
95
-- ❌ 问题:对大表查询未加限制
96
96
SELECT * FROM events ORDER BY timestamp DESC ;
97
97
98
- -- ✅ 解决方案 :始终限制探索性查询的结果集大小
98
+ -- ✅ 解决 :始终限制探索性查询的结果集大小
99
99
SELECT * FROM events ORDER BY timestamp DESC LIMIT 1000 ;
100
100
```
101
101
102
- ### 问题 2:低效的连接 (Join)
102
+ ### 问题 2:低效的连接
103
103
``` sql
104
104
-- ❌ 问题:笛卡尔积
105
105
SELECT * FROM table1, table2 WHERE condition;
106
106
107
- -- ✅ 解决方案 :使用带有正确条件的显式连接
107
+ -- ✅ 解决 :使用带有正确条件的显式连接
108
108
SELECT * FROM table1 t1
109
109
INNER JOIN table2 t2 ON t1 .id = t2 .foreign_id
110
110
WHERE condition;
111
111
```
112
112
113
113
### 问题 3:不必要的复杂性
114
114
``` sql
115
- -- ❌ 问题:嵌套子查询 (Subquery)
115
+ -- ❌ 问题:嵌套子查询
116
116
SELECT * FROM (
117
117
SELECT * FROM (
118
118
SELECT col1, col2 FROM table WHERE condition1
119
119
) WHERE condition2
120
120
) WHERE condition3;
121
121
122
- -- ✅ 解决方案 :合并条件
122
+ -- ✅ 解决 :合并条件
123
123
SELECT col1, col2 FROM table
124
124
WHERE condition1 AND condition2 AND condition3;
125
125
```
126
126
127
127
## 监控与指标
128
128
129
- ### 关键性能指标 (Key Performance Indicators)
130
- - ** 查询执行时间 (Query Execution Time) **
129
+ ### 关键性能指标
130
+ - ** 查询执行时间**
131
131
- ** 扫描行数 vs 返回行数**
132
- - ** 内存使用量 (Memory Usage) **
133
- - ** CPU 使用率 (CPU Utilization) **
134
- - ** I/O 操作 (I/O Operations) **
132
+ - ** 内存使用量**
133
+ - ** CPU 使用率**
134
+ - ** I/O 操作**
135
135
136
136
### 性能监控查询
137
137
``` sql
@@ -155,26 +155,26 @@ LIMIT 10;
155
155
- [ ] 通过选择列来最小化扫描的数据量
156
156
- [ ] 在连接前应用过滤器
157
157
- [ ] 使用正确的连接类型
158
- - [ ] 适当地限制结果集
158
+ - [ ] 适当限制结果集
159
159
160
- ### 索引 (Indexing)
160
+ ### 索引
161
161
- [ ] 为频繁过滤的列创建索引
162
162
- [ ] 为连接列创建索引
163
163
- [ ] 移除未使用的索引
164
164
- [ ] 监控索引的有效性
165
165
166
- ### 模式设计 (Schema Design)
166
+ ### 模式设计
167
167
- [ ] 选择合适的数据类型
168
- - [ ] 适度规范化 (避免过度规范化)
169
- - [ ] 考虑为大表进行分区 (Partitioning)
170
- - [ ] 使用聚簇键 (Cluster Key) 进行排序优化
168
+ - [ ] 适当进行规范化 (避免过度规范化)
169
+ - [ ] 对大表考虑使用分区
170
+ - [ ] 使用聚簇键进行排序优化
171
171
172
172
## 高级优化
173
173
174
- ### 物化视图 (Materialized Views)
174
+ ### 聚合索引
175
175
``` sql
176
- -- 预计算开销大的聚合
177
- CREATE MATERIALIZED VIEW daily_sales AS
176
+ -- 使用 Databend 的聚合索引预计算昂贵的聚合操作
177
+ CREATE AGGREGATING INDEX daily_sales_agg AS
178
178
SELECT
179
179
DATE (order_time) as order_date,
180
180
product_id,
@@ -184,18 +184,18 @@ FROM orders
184
184
GROUP BY DATE (order_time), product_id;
185
185
```
186
186
187
- ### 查询提示 (Query Hints)
187
+ ### 查询提示
188
188
``` sql
189
- -- 在需要时强制使用特定的连接算法
189
+ -- 必要时强制使用特定的连接算法
190
190
SELECT /* + USE_HASH_JOIN */ *
191
191
FROM large_table l
192
192
JOIN small_table s ON l .id = s .foreign_id ;
193
193
```
194
194
195
195
## 最佳实践总结
196
196
197
- 1 . ** 首先测量** - 使用查询概况 (Query Profile) 识别瓶颈
198
- 2 . ** 策略性地创建索引** - 覆盖你的查询模式
199
- 3 . ** 尽早过滤** - 尽快应用 WHERE 条件
200
- 4 . ** 适当限制** - 不要获取超出需要的数据
201
- 5 . ** 持续监控** - 长期跟踪查询性能
197
+ 1 . ** 首先测量** - 使用查询分析识别瓶颈
198
+ 2 . ** 策略性地创建索引** - 覆盖你的查询模式
199
+ 3 . ** 尽早过滤** - 尽快应用 WHERE 条件
200
+ 4 . ** 适当限制** - 不要获取超出需要的数据
201
+ 5 . ** 持续监控** - 长期跟踪查询性能
0 commit comments