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