小数据库表(Oracle)对于SELECT * FROM仍然有巨大的执行时间

时间:2019-02-08 07:12:18

标签: sql oracle oracle11g query-performance

我在Oracle 12c中有一个很小的表。它有大约4.5万条记录,大小为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 

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

2 个答案:

答案 0 :(得分:1)

与DBA联络后,我们发现上述查询主要在等待库高速缓存锁定和库高速缓存引脚等待事件。该表作为依赖对象在其上创建了十万多个视图(具有动态名称,如VW_TABLE_12345,VW_TABLE_12346等),这显然是一个非常糟糕的设计。当我们更改代码并清除所有视图时,表达到了应有的速度

答案 1 :(得分:0)

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

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

第二,是ID不是数字。如果它是字符串,则该列将被转换为数字,这可能会阻止使用索引。

还有其他可能性,但似乎最有可能。