慢查询怎么解决

1. 慢查询日志分析

启用SQL跟踪

-- 会话级跟踪
ALTER SESSION SET SQL_TRACE = TRUE;

-- 实例级跟踪(需要DBA权限)
ALTER SYSTEM SET SQL_TRACE = TRUE;

-- 使用DBMS_SESSION跟踪特定会话
EXEC DBMS_SESSION.set_sql_trace(sql_trace => TRUE);

使用AWR报告

-- 生成AWR报告
@$ORACLE_HOME/rdbms/admin/awrrpt.sql

-- 查看TOP SQL
SELECT * FROM v$sqlarea 
WHERE executions > 0 
ORDER BY elapsed_time/executions DESC;

使用ASH报告

-- 实时活动会话历史
SELECT * FROM v$active_session_history 
WHERE sql_id IS NOT NULL 
ORDER BY sample_time DESC;

2. 使用EXPLAIN PLAN分析执行计划

生成执行计划

-- 生成执行计划
EXPLAIN PLAN FOR 
SELECT * FROM employees e JOIN departments d ON e.dept_id = d.dept_id;

-- 查看执行计划
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

分析关键指标

  • Cost: 查询成本估算
  • Cardinality: 预估返回行数
  • Access Path: 数据访问路径
  • Join Method: 连接方式(Nested Loop、Hash Join、Sort Merge Join)

3. 缓存优化

共享池优化

-- 查看共享池使用情况
SELECT * FROM v$sgastat WHERE pool = 'shared pool';

-- SQL共享游标分析
SELECT sql_id, child_number, executions, plan_hash_value
FROM v$sql 
WHERE sql_text LIKE '%your_query%';

结果缓存

-- 启用结果缓存
SELECT /*+ RESULT_CACHE */ employee_id, first_name, last_name 
FROM employees 
WHERE department_id = 10;

4. 索引优化

创建合适的索引

-- 单列索引
CREATE INDEX idx_emp_dept ON employees(department_id);

-- 复合索引(遵循前缀原则)
CREATE INDEX idx_emp_name ON employees(last_name, first_name);

-- 函数索引
CREATE INDEX idx_emp_upper_name ON employees(UPPER(last_name));

-- 位图索引(适用于低基数列)
CREATE BITMAP INDEX idx_emp_status ON employees(status);

索引监控

-- 监控索引使用情况
ALTER INDEX idx_emp_dept MONITORING USAGE;

-- 查看索引使用统计
SELECT * FROM v$object_usage WHERE index_name = 'IDX_EMP_DEPT';

5. 物化视图优化

创建物化视图

-- 创建快速刷新物化视图
CREATE MATERIALIZED VIEW mv_emp_dept
REFRESH FAST ON DEMAND
AS
SELECT e.department_id, d.department_name, COUNT(*) emp_count
FROM employees e, departments d
WHERE e.department_id = d.department_id
GROUP BY e.department_id, d.department_name;

-- 刷新物化视图
EXEC DBMS_MVIEW.REFRESH('mv_emp_dept');

6. 分区表策略

范围分区

-- 按日期范围分区
CREATE TABLE sales (
    sale_id NUMBER,
    sale_date DATE,
    amount NUMBER
) PARTITION BY RANGE (sale_date) (
    PARTITION sales_q1 VALUES LESS THAN (DATE '2023-04-01'),
    PARTITION sales_q2 VALUES LESS THAN (DATE '2023-07-01'),
    PARTITION sales_q3 VALUES LESS THAN (DATE '2023-10-01'),
    PARTITION sales_q4 VALUES LESS THAN (DATE '2024-01-01')
);

哈希分区

-- 按哈希分区
CREATE TABLE customers (
    customer_id NUMBER,
    customer_name VARCHAR2(100)
) PARTITION BY HASH (customer_id) PARTITIONS 4;

7. 并行查询优化

启用并行查询

-- SQL级别并行
SELECT /*+ PARALLEL(employees, 4) */ * FROM employees;

-- 表级别并行
ALTER TABLE employees PARALLEL 4;

-- 会话级别并行
ALTER SESSION ENABLE PARALLEL DML;

8. 统计信息维护

更新统计信息

-- 收集表统计信息
EXEC DBMS_STATS.GATHER_TABLE_STATS('HR', 'EMPLOYEES');

-- 收集索引统计信息
EXEC DBMS_STATS.GATHER_INDEX_STATS('HR', 'IDX_EMP_DEPT');

-- 收集整个schema统计信息
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('HR');

9. SQL优化技巧

使用绑定变量

-- 好的做法:使用绑定变量
SELECT * FROM employees WHERE employee_id = :emp_id;

-- 避免硬编码值
SELECT * FROM employees WHERE employee_id = 100;

优化连接查询

-- 使用适当的连接方式hint
SELECT /*+ USE_NL(e d) */ e.first_name, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id;

10. 内存优化

调整SGA参数

-- 查看SGA配置
SHOW SGA;

-- 调整缓冲区缓存大小
ALTER SYSTEM SET db_cache_size = 1G SCOPE=BOTH;

-- 调整共享池大小
ALTER SYSTEM SET shared_pool_size = 512M SCOPE=BOTH;

综合优化流程

  1. 识别慢查询:通过AWR报告和V$SQL视图识别TOP SQL
  2. 分析执行计划:使用EXPLAIN PLAN分析查询路径
  3. 检查统计信息:确认统计信息是否最新
  4. 索引优化:添加或调整索引
  5. SQL重写:优化查询语句结构
  6. 资源调整:根据需要调整内存和并行度
  7. 监控效果:持续监控优化后的性能表现
posted @ 2025-08-25 21:15  一刹流云散  阅读(12)  评论(0)    收藏  举报