查看表分析结果如下:

统计信息被显式锁定
使用
DBMS_STATS.LOCK_TABLE_STATS 或
DBMS_STATS.LOCK_SCHEMA_STATS 手动锁定了统计信息。
数据导入(IMP/IMPDP)触发锁定
使用
ROWS=N 参数导入表结构(不导入数据)时,Oracle 会自动锁定统计信息(常见于 10gR2 及以上版本)。
队列表(Queue Table)的特殊性
队列表因数据频繁变化,Oracle 会默认锁定其统计信息以强制使用动态采样。
-- 语法EXEC DBMS_STATS.UNLOCK_TABLE_STATS('Schema名', '表名');-- 示例EXEC DBMS_STATS.UNLOCK_TABLE_STATS('REPORT', 'SWFLOG');
验证解锁后重新收集统计信息:
EXEC DBMS_STATS.GATHER_TABLE_STATS('REPORT', 'SWFLOG');-- 或ANALYZE TABLE SWFLOG COMPUTE STATISTICS;
2. 解锁整个Schema
-- 解锁Schema下所有表的统计信息EXEC DBMS_STATS.UNLOCK_SCHEMA_STATS('Schema名');-- 示例EXEC DBMS_STATS.UNLOCK_SCHEMA_STATS('HR');
3. 批量生成解锁脚本
若需解锁多张表,可生成动态SQL:
SELECT 'EXEC DBMS_STATS.UNLOCK_TABLE_STATS(''' || OWNER || ''',''' || TABLE_NAME || ''');' FROM DBA_TAB_STATISTICS
WHERE STATTYPE_LOCKED IS NOT NULL AND OWNER = 'Schema名'; -- 替换为实际Schema名
执行生成的SQL即可解锁所有被锁定的表。
确认被锁定的对象
查询锁定表:
-- 当前用户下被锁定的表SELECT TABLE_NAME FROM USER_TAB_STATISTICS WHERE STATTYPE_LOCKED IS NOT NULL;-- 全库范围(需DBA权限)SELECT OWNER, TABLE_NAME FROM DBA_TAB_STATISTICS WHERE STATTYPE_LOCKED IS NOT NULL;
执行解锁操作
单表解锁:
EXEC DBMS_STATS.UNLOCK_TABLE_STATS('用户', '表名');
Schema解锁:
EXEC DBMS_STATS.UNLOCK_SCHEMA_STATS('用户');
重新收集统计信息
EXEC DBMS_STATS.GATHER_TABLE_STATS('Schema名', '表名');
避免非必要锁定
除非需固定执行计划,否则谨慎使用
LOCK_TABLE_STATS。
导入数据后检查
使用
IMPDP/IMP 导入时,若指定
ROWS=N,导入后需主动解锁统计信息。
队列表无需处理
若表为队列表(如
AQ$_*),其统计信息锁定是正常行为,无需解锁。
ORA-20005:与 ORA-38029 本质相同,均为统计信息锁定导致,解决方法一致。
适用版本:以上方案适用于 Oracle 10gR2 至 9c 所有版本。
| 可能原因 | 解决方案 | 操作命令示例 |
|---|---|---|
| 单表被锁定 | 解锁单表 |
EXEC DBMS_STATS.UNLOCK_TABLE_STATS('HR', 'EMPLOYEES'); |
| 整个Schema被锁定 | 解锁Schema |
EXEC DBMS_STATS.UNLOCK_SCHEMA_STATS('HR'); |
| 多表被锁定 | 批量生成解锁脚本 | 见上文SQL生成脚本 |
✅ 关键提示:解锁后需重新收集统计信息(
GATHER_TABLE_STATS),否则优化器可能使用过时统计信息生成低效执行计划。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10201716/viewspace-3089545/ ,如需转载,请注明出处,否则将追究法律责任。