小型 DB table (Oracle) SELECT * FROM 的执行时间仍然很长

Small DB table (Oracle) still huge execution time for SELECT * FROM

我在 Oracle 12c 中有一个很小的 ​​table。它有大约 45K 条记录,大小为 12MB(根据最近的收集统计数据)。但是 运行

需要 30 秒到 1 分 30 秒
SELECT * FROM table_name;

另外如果我 运行

SELECT * FROM TABLE WHERE ID = 123

(其中 id 是一个索引列)它也需要大约 45 秒。

有什么问题吗?

更新: 按要求解释计划。

SELECT * FROM {table_name}

SELECT STATEMENT  ALL_ROWSCost: 410  Bytes: 14,733,600  Cardinality: 43,850      
    1 TABLE ACCESS FULL TABLE {table_name} Cost: 410  Bytes: 14,733,600  Cardinality: 43,850  


SELECT * FROM {table_name} WHERE id = 123

SELECT STATEMENT  ALL_ROWSCost: 2  Bytes: 672  Cardinality: 2          
    2 TABLE ACCESS BY INDEX ROWID BATCHED TABLE {table_name} Cost: 2  Bytes: 672  Cardinality: 2      
        1 INDEX RANGE SCAN INDEX {index_name} Cost: 1  Cardinality: 2 

很抱歉隐藏对象名称以符合组织政策

很多事情可能是错误的,但我想到了两个。

首先是您使用 WHERE ID = 123 的查询返回了大量行。超过某个阈值,数据库将决定完整 table 扫描比使用索引更有效。这与索引中值的基数 的想法有关。

其次,ID不是数字。如果它是一个字符串,那么该列将被转换为一个数字,这可能会阻止使用索引。

还有其他可能性,但这些似乎是最有可能的。

在与 DBA 联系后,我们发现上面的查询主要是在等待库缓存锁和库缓存引脚等待事件。 table 有超过十万个视图(动态名称如 VW_TABLE_12345、VW_TABLE_12346 等)作为依赖对象在其上创建,这显然是一个非常糟糕的设计。当我们更改代码并清除所有视图时,table 和应该的一样快