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

问题描述 投票:1回答:2

我在Oracle 12c有一张很小的桌子。它有大约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 

抱歉,隐藏对象名称以符合组织策略

sql oracle oracle11g query-performance
2个回答
1
投票

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


0
投票

多件事可能是错的,但有两个想到。

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

第二,是ID不是一个数字。如果它是一个字符串,那么该列将被转换为一个数字,这可能会妨碍使用索引。

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

© www.soinside.com 2019 - 2024. All rights reserved.