我在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
抱歉,隐藏对象名称以符合组织策略
在与DBA联系之后,我们发现上面的查询主要是等待库缓存锁和库缓存引脚等待事件。该表有超过十万个视图(使用动态名称,如VW_TABLE_12345,VW_TABLE_12346等)作为依赖对象创建,这显然是一个非常糟糕的设计。当我们更改代码并清除所有视图时,表格尽可能快
多件事可能是错的,但有两个想到。
首先,您使用WHERE ID = 123
的查询返回了大量行。超过某个阈值,数据库将确定全表扫描比使用索引更有效。这与索引中值的基数的概念有关。
第二,是ID
不是一个数字。如果它是一个字符串,那么该列将被转换为一个数字,这可能会妨碍使用索引。
还有其他可能性,但这些似乎最有可能。