SQL 查询慢问题诊断与优化实践

定位慢查询

金仓数据库提供 sys_stat_statements 扩展,可统计 SQL 的执行频率、总耗时和平均耗时。

-- 启用扩展(需在 kingbase.conf 中配置 shared_preload_libraries) CREATE EXTENSION IF NOT EXISTS sys_stat_statements; -- 查询耗时 TOP 10 的 SQL SELECT total_exec_time / calls AS avg_ms, calls, total_exec_time, query FROM sys_stat_statements ORDER BY total_exec_time DESC LIMIT 10;

也可开启慢查询日志,直接在日志中捕获慢 SQL:

# 在 kingbase.conf 中设置(单位:ms) log_min_duration_statement = 1000 # 超过 1 秒记录日志 log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '

使用 EXPLAIN ANALYZE 分析执行计划

EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT * FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = 'pending' AND o.created_at > '2025-01-01';
i

重点关注执行计划中的 Seq Scan(全表扫描)节点。若出现在大表上,通常意味着索引缺失或未被使用。

常见慢查询原因与优化方案

原因一:缺少索引

-- 为高频过滤列添加索引 CREATE INDEX CONCURRENTLY idx_orders_status_created ON orders (status, created_at); -- 对于多列查询,注意索引列顺序:选择性高的列放前面

原因二:统计信息过旧

-- 手动更新统计信息 ANALYZE orders; -- 查看统计信息最后更新时间 SELECT relname, last_analyze, last_autoanalyze FROM sys_stat_user_tables WHERE relname = 'orders';

原因三:连接池不足导致排队

-- 查看当前连接数 SELECT count(*), state FROM sys_stat_activity GROUP BY state; -- 查看等待锁的会话 SELECT pid, query, wait_event_type, wait_event, state FROM sys_stat_activity WHERE wait_event_type = 'Lock';

原因四:大表缺少分区

对于超过 1000 万行的历史数据表,建议按时间字段进行范围分区,将查询限定在特定分区内。

-- 创建按年分区的表 CREATE TABLE orders_2025 PARTITION OF orders FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');

性能参数调优参考

参数 推荐值(8C 32G) 说明
shared_buffers 8GB 共享缓冲区,建议为内存的 25%
work_mem 64MB 每个排序/哈希操作的内存
maintenance_work_mem 1GB VACUUM/CREATE INDEX 使用的内存
effective_cache_size 24GB 操作系统缓存估算值(影响执行计划)
max_parallel_workers_per_gather 4 单查询并行度

 

上一篇 【转载】HCIE R&S 备考笔记 HCIE Security 二层攻击防范 备考笔记(幕布)
下一篇 网关=上网钥匙?这3种情况没有网关也可以上网