1. 首页 > GreenPlum教程 > 正文

GreenPlum教程FG020-GreenPlum慢查询优化实战

本文档风哥主要介绍GreenPlum慢查询优化,包括慢查询概念、慢查询原因、慢查询优化最佳实践、慢查询分析、慢查询优化、慢查询优化案例等内容,风哥教程参考GreenPlum官方文档Administrator Guide、Query Performance等内容编写,适合DBA人员在学习和测试中使用。

Part01-基础概念与理论知识

1.1 GreenPlum慢查询概念

慢查询是指执行时间超过预期阈值的SQL语句,通常会影响系统性能和用户体验。更多视频教程www.fgedu.net.cn

1.1.1 慢查询定义

慢查询定义:

1. 时间阈值
– 默认:执行时间超过1秒
– 可根据业务调整
– OLTP系统:500ms
– OLAP系统:10秒

2. 影响因素
– 查询复杂度
– 数据量大小
– 系统负载
– 并发情况

3. 常见类型
– 全表扫描
– 复杂关联查询
– 大数据量聚合
– 子查询嵌套

4. 监控方式
– pg_stat_activity视图
– 慢查询日志
– 性能监控工具
– 自定义监控脚本

1.2 GreenPlum慢查询原因

慢查询的产生有多种原因,需要分析具体情况进行优化。学习交流加群风哥微信: itpux-com

1.2.1 常见原因

GreenPlum慢查询常见原因:

1. SQL问题
– 缺少索引
– 不合理的关联
– 复杂子查询
– 使用函数导致索引失效

2. 数据分布问题
– 数据倾斜
– 分布键选择不当
– 分区设计不合理
– 统计信息过期

3. 系统资源问题
– 内存不足
– I/O瓶颈
– CPU资源紧张
– 网络延迟

4. 并发问题
– 锁等待
– 资源竞争
– 连接数过多
– 事务过长

5. 配置问题
– 参数设置不当
– 内存分配不合理
– 并行度设置错误
– 工作内存不足

Part02-生产环境规划与建议

2.1 GreenPlum慢查询优化最佳实践

风哥提示:慢查询优化最佳实践:

  • 定期收集统计信息
  • 合理设计索引
  • 优化SQL语句
  • 调整系统参数
  • 监控慢查询日志

Part03-生产环境项目实施方案

3.1 GreenPlum慢查询分析实战

3.1.1 识别慢查询

# 连接数据库
$ psql -d fgedudb -U fgedu
psql (9.4.26)
Type “help” for help.

fgedudb=>

# 查看当前活动查询
fgedudb=> SELECT
fgedudb-> pid,
fgedudb-> usename,
fgedudb-> application_name,
fgedudb-> state,
fgedudb-> query_start,
fgedudb-> now() – query_start AS duration,
fgedudb-> query
fgedudb-> FROM pg_stat_activity
fgedudb-> WHERE state = ‘active’
fgedudb-> AND now() – query_start > interval ‘5 seconds’
fgedudb-> ORDER BY query_start;
pid | usename | application_name | state | query_start | duration | query
——-+———+——————+——–+——————————-+—————–+————————————–
12345 | fgedu | psql | active | 2026-04-08 10:00:00.123456+08 | 00:00:30.123456 | SELECT * FROM fgedu.fgedu_order WHERE…
(1 row)

# 查看历史慢查询(需要启用日志)
$ grep “duration:” /GreenPlum/log/gpdb-*.csv | grep -E “duration: [0-9]{4,}\.” | tail -10
2026-04-08 10:00:00.123 CST,”fgedu”,”fgedudb”,12345,”[local]”,123456,2026-04-08 09:59:30 CST,0,LOG,00000,”duration: 30000.123 ms statement: SELECT * FROM fgedu.fgedu_order WHERE create_date > ‘2024-01-01′”,,,,,,,,”psql”

学习交流加群风哥QQ113257174

3.1.2 分析执行计划

# 使用EXPLAIN分析查询
fgedudb=> EXPLAIN ANALYZE
fgedudb-> SELECT
fgedudb-> o.order_id,
fgedudb-> c.customer_name,
fgedudb-> SUM(o.amount) AS total_amount
fgedudb-> FROM fgedu.fgedu_order o
fgedudb-> JOIN fgedu.fgedu_customer c ON o.customer_id = c.customer_id
fgedudb-> WHERE o.order_date >= ‘2024-01-01’
fgedudb-> GROUP BY o.order_id, c.customer_name;
QUERY PLAN
————————————————————————————————————————-
Gather Motion 2:1 (slice1; segments: 2) (cost=50000.00..60000.00 rows=10000 width=100) (actual time=30000.123..30050.456 rows=10000 loops=1)
-> HashAggregate (cost=50000.00..60000.00 rows=10000 width=100) (actual time=29900.123..30000.456 rows=10000 loops=1)
Group Key: o.order_id, c.customer_name
-> Hash Join (cost=10000.00..40000.00 rows=1000000 width=100) (actual time=5000.123..25000.456 rows=1000000 loops=1)
Hash Cond: (o.customer_id = c.customer_id)
-> Seq Scan on fgedu_order o (cost=0.00..20000.00 rows=1000000 width=50) (actual time=0.123..10000.456 rows=1000000 loops=1)
Filter: (order_date >= ‘2024-01-01’::date)
Rows Removed by Filter: 500000
-> Hash (cost=5000.00..5000.00 rows=100000 width=50) (actual time=5000.123..5000.456 rows=100000 loops=1)
Buckets: 131072 Batches: 2 Memory Usage: 5120kB
-> Seq Scan on fgedu_customer c (cost=0.00..5000.00 rows=100000 width=50) (actual time=0.123..3000.456 rows=100000 loops=1)
Optimizer: Postgres query optimizer
Total runtime: 30100.789 ms
(12 rows)

更多学习教程公众号风哥教程itpux_com

3.2 GreenPlum慢查询优化实战

3.2.1 创建索引优化

# 分析发现fgedu_order表的order_date列缺少索引

# 创建索引
fgedudb=> CREATE INDEX idx_fgedu_order_date
fgedudb-> ON fgedu.fgedu_order(order_date);
CREATE INDEX

# 更新统计信息
fgedudb=> ANALYZE fgedu.fgedu_order;
ANALYZE

# 再次执行查询
fgedudb=> EXPLAIN ANALYZE
fgedudb-> SELECT
fgedudb-> o.order_id,
fgedudb-> c.customer_name,
fgedudb-> SUM(o.amount) AS total_amount
fgedudb-> FROM fgedu.fgedu_order o
fgedudb-> JOIN fgedu.fgedu_customer c ON o.customer_id = c.customer_id
fgedudb-> WHERE o.order_date >= ‘2024-01-01’
fgedudb-> GROUP BY o.order_id, c.customer_name;
QUERY PLAN
————————————————————————————————————————-
Gather Motion 2:1 (slice1; segments: 2) (cost=10000.00..20000.00 rows=10000 width=100) (actual time=5000.123..5050.456 rows=10000 loops=1)
-> HashAggregate (cost=10000.00..20000.00 rows=10000 width=100) (actual time=4900.123..5000.456 rows=10000 loops=1)
Group Key: o.order_id, c.customer_name
-> Hash Join (cost=5000.00..15000.00 rows=1000000 width=100) (actual time=1000.123..4000.456 rows=1000000 loops=1)
Hash Cond: (o.customer_id = c.customer_id)
-> Index Scan using idx_fgedu_order_date on fgedu_order o (cost=0.00..10000.00 rows=1000000 width=50) (actual time=0.123..2000.456 rows=1000000 loops=1)
Index Cond: (order_date >= ‘2024-01-01’::date)
-> Hash (cost=5000.00..5000.00 rows=100000 width=50) (actual time=1000.123..1000.456 rows=100000 loops=1)
Buckets: 131072 Batches: 1 Memory Usage: 5120kB
-> Seq Scan on fgedu_customer c (cost=0.00..5000.00 rows=100000 width=50) (actual time=0.123..500.456 rows=100000 loops=1)
Optimizer: Postgres query optimizer
Total runtime: 5100.789 ms
(12 rows)

# 查询时间从30秒降低到5秒,性能提升6倍

from GreenPlum视频:www.itpux.com

3.2.2 SQL语句优化

# 优化前:使用子查询
fgedudb=> EXPLAIN ANALYZE
fgedudb-> SELECT * FROM fgedu.fgedu_order
fgedudb-> WHERE customer_id IN (
fgedudb(> SELECT customer_id FROM fgedu.fgedu_customer WHERE city = ‘北京’
fgedudb(> );
QUERY PLAN
————————————————————————————————————————-
Gather Motion 2:1 (slice1; segments: 2) (cost=10000.00..50000.00 rows=100000 width=100) (actual time=10000.123..15000.456 rows=100000 loops=1)
-> Seq Scan on fgedu_order (cost=10000.00..50000.00 rows=100000 width=100) (actual time=9000.123..14000.456 rows=100000 loops=1)
Filter: (SubPlan 1)
SubPlan 1
-> Materialize (cost=0.00..10000.00 rows=10000 width=4) (actual time=0.001..0.010 rows=1 loops=100000)
-> Seq Scan on fgedu_customer (cost=0.00..10000.00 rows=10000 width=4) (actual time=0.123..100.456 rows=10000 loops=1)
Filter: (city = ‘北京’::text)
Total runtime: 16000.789 ms
(8 rows)

# 优化后:使用JOIN
fgedudb=> EXPLAIN ANALYZE
fgedudb-> SELECT o.* FROM fgedu.fgedu_order o
fgedudb-> JOIN fgedu.fgedu_customer c ON o.customer_id = c.customer_id
fgedudb-> WHERE c.city = ‘北京’;
QUERY PLAN
————————————————————————————————————————-
Gather Motion 2:1 (slice1; segments: 2) (cost=5000.00..15000.00 rows=100000 width=100) (actual time=1000.123..1500.456 rows=100000 loops=1)
-> Hash Join (cost=5000.00..15000.00 rows=100000 width=100) (actual time=900.123..1400.456 rows=100000 loops=1)
Hash Cond: (o.customer_id = c.customer_id)
-> Seq Scan on fgedu_order o (cost=0.00..10000.00 rows=100000 width=100) (actual time=0.123..500.456 rows=100000 loops=1)
-> Hash (cost=4000.00..4000.00 rows=10000 width=4) (actual time=500.123..500.456 rows=10000 loops=1)
Buckets: 16384 Batches: 1 Memory Usage: 480kB
-> Seq Scan on fgedu_customer c (cost=0.00..4000.00 rows=10000 width=4) (actual time=0.123..300.456 rows=10000 loops=1)
Filter: (city = ‘北京’::text)
Total runtime: 1600.789 ms
(9 rows)

# 查询时间从16秒降低到1.6秒,性能提升10倍

Part04-生产案例与实战讲解

4.1 GreenPlum慢查询优化案例

4.1.1 综合优化案例

# 场景:销售报表查询慢

# 原始查询(执行时间60秒)
SELECT
d.dept_name,
p.product_name,
COUNT(*) AS order_count,
SUM(o.amount) AS total_amount
FROM fgedu.fgedu_order o
JOIN fgedu.fgedu_customer c ON o.customer_id = c.customer_id
JOIN fgedu.fgedu_dept d ON c.dept_id = d.dept_id
JOIN fgedu.fgedu_product p ON o.product_id = p.product_id
WHERE o.order_date BETWEEN ‘2024-01-01’ AND ‘2024-12-31’
GROUP BY d.dept_name, p.product_name
ORDER BY total_amount DESC;

# 优化步骤:

# 1. 创建索引
CREATE INDEX idx_fgedu_order_date ON fgedu.fgedu_order(order_date);
CREATE INDEX idx_fgedu_order_product ON fgedu.fgedu_order(product_id);
CREATE INDEX idx_fgedu_customer_dept ON fgedu.fgedu_customer(dept_id);

# 2. 更新统计信息
ANALYZE fgedu.fgedu_order;
ANALYZE fgedu.fgedu_customer;
ANALYZE fgedu.fgedu_dept;
ANALYZE fgedu.fgedu_product;

# 3. 优化SQL(使用分区裁剪)
SELECT
d.dept_name,
p.product_name,
COUNT(*) AS order_count,
SUM(o.amount) AS total_amount
FROM fgedu.fgedu_order o
JOIN fgedu.fgedu_customer c ON o.customer_id = c.customer_id
JOIN fgedu.fgedu_dept d ON c.dept_id = d.dept_id
JOIN fgedu.fgedu_product p ON o.product_id = p.product_id
WHERE o.order_date >= ‘2024-01-01’
AND o.order_date < '2025-01-01' GROUP BY d.dept_name, p.product_name ORDER BY total_amount DESC; # 优化后执行时间:5秒,性能提升12倍

Part05-风哥经验总结与分享

5.1 GreenPlum慢查询优化技巧

慢查询优化技巧:

1. 索引优化
– 为常用查询条件创建索引
– 避免过度索引
– 定期维护索引
– 使用复合索引

2. SQL优化
– 避免SELECT *
– 使用JOIN代替子查询
– 合理使用WHERE条件
– 避免函数导致索引失效

3. 统计信息优化
– 定期收集统计信息
– 数据变化后及时更新
– 设置合理的采样率
– 监控统计信息准确性

4. 系统参数优化
– 调整工作内存
– 优化并行度
– 设置合理的成本参数
– 调整连接池大小

5. 监控与维护
– 定期监控慢查询日志
– 建立性能基线
– 定期优化查询
– 文档化优化过程

本文档介绍了GreenPlum慢查询优化的核心内容,包括慢查询分析、慢查询优化、优化案例等,希望对大家有所帮助。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息