SQL 与执行计划
找出正在跑的重活
SELECT sql_id, elapsed_time/1000000 AS sec, executions, sql_text
FROM v$sql
WHERE elapsed_time > 1e7
ORDER BY elapsed_time DESC
FETCH FIRST 20 ROWS ONLY;
历史可以用 AWR / ASH(许可允许时)。没有许可就看 v$sql、v$session、操作系统的等待。
看计划
SELECT * FROM table(dbms_xplan.display_cursor('8ab12cde3f90a', NULL, 'ALLSTATS LAST'));
关注:
TABLE ACCESS FULL是否合理- 估算行数和实际行数差一个数量级
- 嵌套循环对外表太大
- 有没有多余的
VIEW/FILTER
绑定变量窥视会导致第一次计划被后续不同数据量复用。遇到「同一条 SQL 时快时慢」,把这点算进去。
统计信息
SELECT table_name, num_rows, last_analyzed
FROM dba_tables
WHERE owner = 'APP_USER'
ORDER BY last_analyzed;
统计过旧,优化器会选错。收集统计是维护,不是调优咒语,不要在高峰对超大表做全量锁统计。