我有一个表,其中有很多索引。我注意到其中之一中的“ DISTINCT_KEYS”与“ NUM_ROWS”几乎相同。是否需要这样的索引?
或者最好删除它,因为:
您怎么看?删除此索引会降低使用此列名称的查询的速度吗?
答案 0 :(得分:4)
需要这样的索引吗?
您可以从DISTINCT_KEYS
和NUM_ROWS
这样的统计数据(以及其他统计数据,例如直方图)中看出,索引可能是否有用。仅当系统中的查询实际使用索引时,才真正“需要”索引。 (请参见ALTER INDEX ... MONITORING USAGE
命令)
具有DISTINCT_KEYS
几乎等于NUM_ROWS
的索引肯定是有用的。实际上,如果DISTINCT_KEYS
占NUM_ROWS
的比例很低,则怀疑索引无用会更自然。
假设您有一个查询:
SELECT column_x
FROM table_y
WHERE column_z = :some_value
假设column_z
上的索引显示DISTINCT_KEYS
= 999999和NUM_ROWS
= 1000000。
这意味着,平均而言,每个不同的键(非常)多于一行。这使得索引非常具有选择性,并且非常有用。查询运行时,我们将使用索引非常快速地仅提取表的一行。
相反,假设column_z
上的索引显示DISTINCT_KEYS
= 2和NUM_ROWS
=1000000。现在,每个不同的键平均有500,000行。该索引毫无用处,因为我们必须从索引中读取每个块的一半,然后仍然可能需要从表中读取最后一半的块(可能超过一半)。更糟糕的是,这些读取都是单块读取。对于Oracle而言,忽略索引并进行全表扫描会更快,更简单-总共读取的块更少,而所有读取都是多块读取(例如,一次读取8个)。
为完整性起见,我将指出DISTINCT_KEYS
= 2且NUM_ROWS
= 1000000 的索引可能仍然有用,如果数据非常不正确。也就是说,例如,如果一个不同的键只有999,000行,而另一个不同的键只有1,000行。该索引对于查找其他(较小)不同键的行很有用。 Oracle收集直方图作为其统计信息的一部分,以跟踪哪些列的数据倾斜,如果存在,则跟踪每个不同键有多少行。 (过于简化)。