是否有必要考虑删除现有索引,因为它是推荐索引的前缀

时间:2011-08-16 14:00:11

标签: sql performance oracle query-optimization

Oracle SQL Developer v3的SQL Tuning Advisor为我的查询建议了以下内容:

  

考虑运行Access Advisor以改进物理架构   设计       或创建推荐的索引。 如果您选择创建       建议索引,考虑删除索引       “ SCHEMANAME ”。“ INDEXNAME ”(在“COLUMN1”上),因为它是       推荐指数。

create index SCHEMANAME.NEW_INDEXNAME on SCHEMANAME.TABLENAME("COLUMN1","COLUMN2");

以粗体做暗示是否有任何伤害?问题是它建议丢弃的现有索引被其他程序使用。我不认为这些因素可能会“伤害”彼此,是否有任何不利因素将两个索引与它们将占用的磁盘空间区分开来,并且插入/更新时性能下降不明显?

3 个答案:

答案 0 :(得分:9)

因此,假设OLD INDEX在[Column1]上并且RECOMMENDED INDEX在[Column1] [Column2]上,则推荐的索引也可用于现有查询。

简而言之:删除 OLD INDEX将如您所说,提高插入/更新时的效果也不会降低搜索能力< / strong>过度扫描使用OLD INDEX的查询。推荐索引仍允许查找[Column1]值以及[Column1] [Column2]值。

因此,除了更新/插入的性能下降和额外的存储开销之外没有任何损害,但是还有无增益来维护两个索引。

答案 1 :(得分:7)

实际上,当您删除单列上的索引时,性能可能会下降。

假设您使用WHERE [Column1] = 123进行查询。这可以通过原始索引完美地解决。新索引也可用于此,但将依赖于实现 - 需要读取索引中[Column2]的值,即使它们未被使用。

所以是的:从理论上讲,降低指数是一个缺点:增加了读数。

[9月9日更新] 最近我遇到了另一种情况,即单个索引可以比合并索引好得多 考虑一个巨大的表'错误'列[status],[createdate]和其他一些字段。大多数错误将被关闭,因此对于100条记录,状态为“0”(打开),对于99000条记录,状态为“1”(已关闭)。

SELECT * FROM bugs WHERE status = '0'将从status上的索引中受益匪浅,而使用SELECT * FROM bugs WHERE status = '1' status上的索引将无济于事。

Oracle将知道差异,因为它构建了索引的统计信息。

但是,对于status, createdate上的组合索引,每个索引条目几乎是唯一的,Oracle将决定不使用查询SELECT * FROM bugs WHERE status = '0'的索引,因为它猜测(错误地)索引将无法帮助

因此,在这种情况下,不应仅删除单个索引,因为它是组合索引的前缀。

注意:从理论上讲,Oracle可以在索引上构建更智能的统计数据,但似乎并没有这样做。

答案 2 :(得分:5)

不丢弃原始索引的危害是Oracle在只需要一个索引时维护两个索引的开销。

离开它们的缺点是CRUD操作在桌面上的表现有所下降,我从你的帖子中发现,这可能是“微不足道的”,但是随着时间的推移,表格会增长,这将导致你的问题然后必须得到补救。

它还会不必要地占用更多存储空间。

您之前的程序仍然可以使用新索引。

留下不必要的索引会使未来的开发人员和必须支持数据库的DBA感到困惑,这会花费他们的时间和精力来调查重复索引存在的原因。

我没有寻找不放弃原始索引的理由,而是寻找保留它的理由。

放弃它,测试你的“其他”程序的性能,你应该看不出什么区别,如果有问题你可以调查原因,如果有必要更换它。