删除行将改善oracle中的选择性能?

时间:2013-12-10 10:03:30

标签: sql performance oracle

我有一张巨大的桌子(2亿条记录)。现在不需要大约70%(表中有列ACTIVE,那些记录的值为N)。有很多多列索引,但它们都不包含该列。删除70%的记录会改善SELECT(ACTIVE ='Y')性能(因为oracle必须读取没有活动记录的表块,然后将它们从最终结果中排除)?收缩空间是否必要?

5 个答案:

答案 0 :(得分:3)

如果不了解更多有关您的疑问,真的无法说出来。

在一个极端情况下,只有支持索引的高度降低才能提高主键访问权限,这可能需要删除行,然后重建索引。

在另一个极端情况下,如果您选择几乎所有活动记录,那么删除70%行(并且表缩小)的表的完整扫描将只占删除前时间的30%。 / p>

还有许多其他注意事项 - 选择一组数据并通过索引访问表,并且在读取表后需要拒绝99%的行,因为事实证明所需行和非活动之间存在正相关性状态。

处理此问题的一种方法是通过列表对ACTIVE列上的表进行分区。这会将非活动记录移动到可以从许多查询中删除的分区,而无需索引列,并且会保留完整扫描活动记录的时间。

如果您确实不需要这些非活动记录,为什么不删除它们而不是将它们标记为无效?

编辑:此外,尽管使用70/30拆分对列进行索引通常没有帮助,但您可以尝试其他一些索引技巧。

例如,如果您有一个在查询中经常使用的索引列(client_id?),那么您可以将活动标志添加到该索引。您还可以构建部分索引:

 create index my_table_active_clients
 on my_table (case when active = 'Y' then client_id end);

...然后查询:

select ...
from   ...
where  (case when active = 'Y' then client_id end) = :client_id

这会使索引更小,两种索引方法都可能会有所帮助。

另一个编辑:分区的有益副作用可能是它使非活动记录和活动记录“物理”分开,并且从“活动”分区读入内存的每个块当然只有活动记录。这可能会提高您的缓存效率。

答案 1 :(得分:2)

分区,将active ='NO'记录放在一个单独的分区中,可能是个不错的选择。 http://docs.oracle.com/cd/B19306_01/server.102/b14223/parpart.htm

答案 2 :(得分:1)

是的,很有可能。但是根据您的访问模式,增加很可能不会那么大。设置包含该列的索引将是未来恕我直言的更好解决方案。

答案 3 :(得分:0)

很可能没有。删除不会减小表格段的大小。额外维护可能会有所帮DELETE执行后也是:

ALTER TABLE <tablename> SHRINK SPACE COMPACT;
ALTER INDEX <indexname> SHRINK SPACE COMPACT;  -- for every table's index

或者你可以使用旧学校的方法:

ALTER TABLE <tablename> MOVE; 
ALTER INDEX <indexnamename> REBUILD;

当删除70%的表时也考虑可能的解决方案CTAS(创建表作为选择)。它会快得多。

答案 4 :(得分:0)

索引在SELECT查询中起着至关重要的作用。表现将大幅增加 如果您在查询中使用这些索引列。 Ya删除行将提高性能 肯定有些但不是很大。