1. 索引未被创建或未正确创建
确保为查询中涉及的列创建了索引。例如,如果你经常需要按column_name列进行查询,确保已经为该列创建了索引,索引创建语句
CREATE INDEX idx_column_name ON table_name(column_name);
2、索引不可用
原因:索引可能被标记为不可用(UNUSABLE)通常是由于索引重建失败或数据导入操作导致的。
解决方法:检查索引状态并重建索引
检查索引状态
SELECT INDEX_NAME, STATUS FROM USER_INDEXES WHERE TABLE_NAME = 'TABLE_NAME';
如果索引不可用,重建索引
ALTER INDEX INDEX_NAME REBUILD;
3、统计信息不准确
原因:
Oracle 优化器依赖统计信息来决定执行计划。如果表的统计信息不准确或过时,优化器可能会错误地选择不使用索引。
所以创建索引并且执行语句没有问题,则 可以使用DBMS_STATS包来收集最新的统计信息:
解决方法:
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCHEMA_NAME', 'TABLE_NAME');
EXEC DBMS_STATS.GATHER_TABLE_STATS('SYMDR', 'LAB_REPORT_INFO');
4、如果收集最新的统计信息执行报错
错误信息:
ORA-20005: object statistics are locked (stattype = ALL) 则看是否有死锁
SELECT s.sid, s.serial#, l.object_id, o.object_name, l.session_id blocking_sid
FROM v$locked_object l
JOIN dba_objects o ON l.object_id = o.object_id
JOIN v$session s ON l.session_id = s.sid
WHERE o.object_type = 'LAB_REPORT_INFO';
5、终止会话
如果找到死锁可以使用如下命令终止会话
ALTER SYSTEM KILL SESSION 'sid,serial#';
6、强制更新统计信息
如果确定没有其他会话正在使用统计信息,或者已经终止了阻塞会话,可以尝试强制更新统计信息:
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
ownname => 'OWNER',
tabname => 'TABLE_NAME',
estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
method_opt => 'FOR ALL COLUMNS SIZE AUTO',
cascade => TRUE,
force => TRUE);
END;
/
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
ownname => 'SYMDR',
tabname => 'LAB_REPORT_INFO',
estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
method_opt => 'FOR ALL COLUMNS SIZE AUTO',
cascade => TRUE,
force => TRUE);
END;
/
7、 检查执行计划
使用 EXPLAIN PLAN 或 DBMS_XPLAN 查看查询的执行计划,了解优化器为何选择不使用索引:
EXPLAIN PLAN FOR SELECT * FROM TABLE_NAME WHERE COLUMN_NAME = 'VALUE';
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);EXPLAIN PLAN FOR
select * from lab_report_info where org_code='XX' and request_no='XX' and local_id='XX' ;
SELECT * FROM table(DBMS_XPLAN.DISPLAY());