-- 查询数据库时间模型耗时分布(单位:毫秒)SELECT metric_name, total_time, round(total_time /sum(total_time) over () *100, 2) AS time_ratio
FROM sys_time_model
WHERE total_time >0ORDERBY total_time DESC;
3. SQL 调优建议器:新手也能搞定慢 SQL
对于不擅长手动调优的场景,建议器结合参数统计和执行计划,自动生成可执行的优化方案。
以订单慢查询为例:
-- 原始慢 SQL(执行耗时 5.2s,全表扫描)SELECT*FROM order_info WHERE create_time >'2025-01-01'AND user_id =1001;
-- 调用金仓调优建议器(通过系统函数触发)SELECT*FROM sys_sql_tuning_advise(
'SELECT * FROM order_info WHERE create_time > ''2025-01-01'' AND user_id = 1001;'
);
-- 创建联合索引CREATE INDEX idx_user_create ON order_info(user_id, create_time);
-- 优化后查询SELECT order_id, amount, create_time
FROM order_info
WHERE create_time > TO_DATE('2025-01-01', 'YYYY-MM-DD') AND user_id =1001;
二、优化器与执行优化:底层算子重构,解决传统 SQL 痛点
针对传统 SQL 的经典痛点,优化器在底层算子层面进行了深度重构,显著提升性能。
1. NOT IN 子查询优化:从全表扫描到索引连接,速度提 3 倍
金仓优化器会自动将 NOT IN 转换为'左连接+NULL 过滤',并自动走索引。
实测代码对比(数据量 100 万条):
-- 原始 NOT IN 写法(耗时 2.1s)SELECT*FROM user_info WHERE user_id NOTIN (SELECT user_id FROM blacklist);
-- 金仓优化后执行计划对应的 SQL(耗时 0.7s)SELECT u.*FROM user_info u LEFTJOIN blacklist b ON u.user_id = b.user_id WHERE b.user_id ISNULL;
2. OR 转 union all:解决 OR 条件索引失效问题
当 OR 条件涉及不同字段时,金仓会自动将 OR 转换成 union all,分别走对应字段的索引。
实测代码对比:
-- 原始 SQL(OR 条件,全表扫描,耗时 1.5s)SELECT*FROM goods WHERE category_id =10OR price <100;
-- 金仓优化后执行的 SQL(走双索引,耗时 0.2s)SELECT*FROM goods WHERE category_id =10UNIONALLSELECT*FROM goods WHERE price <100AND category_id !=10;
3. UNION 外层条件下推:减少无效数据计算,效率翻倍
金仓智能将外层条件'下推'到每个子查询里,提前过滤无用数据,中间结果集可缩小 80% 以上。
实测代码对比:
-- 原始 SQL(UNION 后过滤,中间结果 10 万条,耗时 2.0s)SELECT*FROM order_202501 UNIONSELECT*FROM order_202502 WHERE create_time >'2025-01-15';
-- 金仓优化后执行的 SQL(条件下推,中间结果 2 万条,耗时 0.4s)SELECT*FROM order_202501 WHERE create_time >'2025-01-15'UNIONSELECT*FROM order_202502 WHERE create_time >'2025-01-15';
4. Agg 排序优化:ListAgg 减少排序次数,聚合更快
金仓优化了算子逻辑,将两次排序合并成一次,直接复用排序结果做聚合。
实测数据对比(无需改 SQL,优化器自动处理):
-- 原始 ListAgg 写法(多次排序,耗时 1.8s)SELECT user_id, LISTAGG(order_id, ',') WITHINGROUP (ORDERBY create_time) AS order_list
FROM order_info GROUPBY user_id;
-- 金仓优化后执行(一次排序,耗时 0.5s)SELECT user_id, LISTAGG(order_id, ',') WITHINGROUP (ORDERBY create_time) AS order_list
FROM order_info GROUPBY user_id;