sql
sql
SELECT merchant_id, SUM(amount), COUNT(DISTINCT user_id)
FROM orders
WHERE create_date >= DATE '2026-01-01'
AND create_date < DATE '2026-08-01'
AND status IN (1,2,3)
GROUP BY merchant_id;
sql
sql
SELECT COUNT(*) FROM (
SELECT merchant_id, SUM(amount), COUNT(DISTINCT user_id)
FROM orders
WHERE create_date >= DATE '2026-01-01'
AND create_date < DATE '2026-08-01'
AND status IN (1,2,3)
GROUP BY merchant_id
) x;
- 现象:页面触发 120s 超时;Navicat 直连 2881 偶发 10~20s 出结果,偶发也超时;
gv$sql_audit 里 elapsed_time 经常 130s+,execute_time 80~120s,queue_time 有时 20~40s。
4 个赞
1)紧急恢复:绑定好计划(Outline)
先用 obclient 直连跑出“快的那次”计划,提 Hint 固化:
sql
sql
CREATE OUTLINE ol_report_orders_count
ON SELECT COUNT(*) FROM (
SELECT /*+ PARALLEL(8) PARTITION_BATCHED_JOIN() */ merchant_id, SUM(amount), COUNT(DISTINCT user_id)
FROM orders
WHERE create_date >= DATE '2026-01-01' AND create_date < DATE '2026-08-01'
AND status IN (1,2,3)
GROUP BY merchant_id
) x;
或更直接:
sql
sql
SELECT /*+ PARALLEL(8) */ COUNT(*) FROM ( 原报表SQL ) x;
验证:
sql
sql
SELECT * FROM oceanbase.gv$outline WHERE outline_name='ol_report_orders_count';
2)根治统计信息 + 动态采样
sql
sql
CALL dbms_stats.gather_table_stats('test','orders', degree=>8, granularity=>'PARTITION');
-- 若仍估行歪,SQL 级强制动态采样
SELECT /*+ DYNAMIC_SAMPLING(4) */ COUNT(*) FROM ( 报表SQL ) x;
3)改写 SQL(最稳)
外层 COUNT(*) 对报表无意义,前端分页即可;非要总数:
sql
sql
-- 轻量总数(走索引覆盖)
SELECT COUNT(*) FROM orders
WHERE create_date >= DATE '2026-01-01'
AND create_date < DATE '2026-08-01'
AND status IN (1,2,3);
报表主体走 GROUP BY 直接返回,不套壳。
4)避开 compaction 毛刺
5)会话级超时与并行度解耦
JDBC 连接池对报表数据源单独设:
sql
sql
SET SESSION ob_query_timeout = 300000000;
SET SESSION parallel_degree_policy = AUTO;
SET SESSION ob_px_parallel_degree = 8;
1 个赞