我有一张表(A),有116,317,979条记录,每天增加约750,000条记录。
根据我的要求,我希望使用日期列从表中有效地获取最后3个完整日数据(日期时间存储在列中)。所以查询将是
select * from A where date_column >= trunc(sysdate) - 3
我还需要将表A加入表B,以便
select * from A
left outer join B
on A.X = B.X and A.Y = B.Y and A.Z = B.Z and B.M = 'XYZ' and B.N = 'UIM'
where A.date_column >= trunc(sysdate) - 3
唯一索引&表B的PK(X,Y,Z,M,N)
唯一索引&表A的PK(ID)
表A中提出的IDX 1(date_column)
表A(X,Y,Z)中建议的IDX 2
Time without Indexes 34 sec
Time with IDX 1 32 sec
Time with IDX 1 & 2 27 sec //Sorry about the mistype
通过仅在A.date_column上添加索引,我认为我可以显着提高性能,但我的测试结果是否定的。除了添加新索引之外,还有其他提示可以提高性能吗?从长远来看,添加这样的索引是否有任何危害。
或
最好创建另一个表并以某种方式在其中填充最近3天的数据(使用db触发器)。我可以轻松地使用另一个流程来清除每晚3天以上的数据。
提前致谢。
答案 0 :(得分:2)
Oracle分区在这里很有意义,但即使对于Enterprise Edition,这也是一个额外的成本选择。 如果分区不可用 - 保留最近3天的单独表应该是最佳的性能。你应该试一试。
如果你想从索引中获得最大值,那么你可以考虑使用物理参数:
PCTFREE 0
trunc(date_column) >= trunc(sysdate) - 3
根据表A中X,Y,Z的选择性,压缩它们也是有意义的。所以我建议检查两个案例:
create index trunc_date_ai on A(trunc(date_column)) pctfree 0 compress;
+您的IDX2 create index trunc_date_ai on A(trunc(date_column),X,Y,Z) pctfree 0 compress;
如果表A中未更新X,Y,Z,则应使用pctfree 0
。
这里compress
关键字对所有4列进行压缩,因此如果X,Y,Z值在表A中对于特定的trunc(date_column)具有高度可重复性,则值得使用。要强制使用索引,您可以提示查询,例如:
select --+ index (A trunc_date_ai)
*
from A left outer join B
on A.X = B.X and A.Y = B.Y and A.Z = B.Z and B.M = 'XYZ' and B.N = 'UIM'
where trunc(A.date_column) >= trunc(sysdate) - 3
答案 1 :(得分:1)
您应该检查执行计划以查看是否正在使用索引。我猜测date_column
上的索引没有被使用,32到34秒之间的差异只是噪音。
对于此查询,我建议使用A(date_column, X, Y, Z)
的索引。
添加索引有害吗?好吧,它们增加了insert
s / update
s / delete
s的开销。如果您的插入是事务性的,那么您每秒插入大约10行 - 不计算更新和删除。如果您的峰值明显高于和,那么您的硬件不是很好,那么索引可能会减慢速度。如果批量添加额外的行,我不会担心开销。
我怀疑将桌子拆分成一个单独的3天桌子会产生很大的不同。但为什么要听我说话?试试看。获取最近3天以上的数据,将其转储到表中,正确索引并查看查询是否更快。