为了加快您的查询速度,添加正确的索引是必不可少的。但过了一段时间,随着系统的增长,您可能会发现大量索引会减慢数据库写入速度——因为每次写入表都需要在事务中更新索引。也许,五年后,您的数据库(和您的查询)已经发展到不再需要某些索引的地步。例如,有一些明显的情况下这两个索引是冗余的:--originaldesignCREATEINDEXONcustomer(first_name);--5年后CREATEINDEXONcustomer(first_name,last_name);但在许多其他情况下,事情并不那么明显。例如......您可能会在外键上添加索引,但随着表的增长,您的数据库开始运行更多的散列连接而不是嵌套循环连接,在这种情况下索引不会被使用。或者,您已经完全停止查找名字/姓氏。或者您已经开始使用比实际名称更具选择性的谓词。或者您的客户突然全都姓史密斯。每个人都叫史密斯-倒霉指数!如果您的索引不再被使用,您可以(并且应该)删除它们。但是如何找到未使用的索引如果您使用的是Oracle数据库,并且您正在访问生产系统,实际上有一个很好的方法来查询诊断表以了解当前正在使用的游标缓存中是否有任何查询你的索引。只需运行:SELECTsql_fulltextFROMv$sqlWHEREsql_idIN(SELECTsql_idFROMv$sql_planWHERE(object_owner,object_name)=(('OWNER','IDX_CUSTOMER_FIRST_NAME')))ORDERBYsql_text;这个查询是做什么的?它运行游标缓存(V$SQL)中的所有SQL语句,并检查它们中的每一个是否在游标缓存(v$sql_plan)访问索引中有任何执行计划元素。结束。当然,如果上面的查询没有返回结果,并不代表没有人在使用你的索引。也可能有一个非常罕见的查询,每年只发生一次,被游标缓存清除。但是,如果将上述查询作为一项作业运行一段时间,您可以得出结论,如果查询未返回任何行,则可能不再需要您的索引。我可以发现不需要的索引吗?当然!运行一个类似的查询来列出所有不引用V$sql_plan表的引用:永远不会使用索引,只是最近没有使用它们。现在,我不会真正向您展示使用上述语句的查询,在PL/SQL循环中运行其结果并使用EXECUTEIMMEDIATE删除所有索引,正如您可能在生产环境中尝试的那样。但是,以防万一你想尝试,这里有一个提示ENDLOOP;END;/但是就像我说的。真的不要做!
