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$sqlv$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;

统计过旧,优化器会选错。收集统计是维护,不是调优咒语,不要在高峰对超大表做全量锁统计。

参考:SQL Tuning Guide