我总是问我自己应该在Oracle表中创建索引,表中的哪些条件会使索引值得创建?它也是查询中的标准吗?您是否(根据Oracle)可以根据某些因素创建不同类型的索引?
答案 0 :(得分:6)
所有这些都是关于针对表格运行的查询,它们的速度有多快,需要它们的速度以及它们运行的频率。如果您需要能够根据它快速查找记录,请将其编入索引。
答案 1 :(得分:2)
当创建UNIQUE约束时,Oracle会自动在列(或列集)上创建唯一索引。索引用于执行约束。
当创建PRIMARY KEY约束时,Oracle还会自动在列(或列集)上创建唯一索引。该索引也用于强制执行约束。 PRIMARY KEY约束和UNIQUE约束之间存在很少但有些差异。
此外,当一列(或一组列)经常用于连接一对表时,应该指定一个外键关系。要做到这一点,引用的列必须是引用表上的主键,这反过来意味着在引用的表上将有一个唯一的(主键)索引。
此外,当在WHERE子句中经常使用特定列(或列集)时,创建索引(唯一或其他)是有意义的。具有特别低基数的列(相对于总行数的低唯一值数),BITMAP索引可能是有利的。 BITMAP索引的利弊可能是一个长期的讨论。
应仔细考虑多列索引中列的顺序。首先,多列索引根本不像相同列上的单个单列索引那样工作,但Oracle很少(如果有的话,特别是没有任何提示)在单个查询上使用多个索引(BITMAP索引是一个可能的例外)。如果你的WHERE子句中通常有A,B和C列,你可能需要A,B和C上的索引。但是,如果你经常在WHERE子句中使用A和C,而没有B,那么你会可能想要将索引中的列排序为A,C,B。当只有A在WHERE子句中时,也可以使用这样的索引。简而言之,Oracle只能通过使用索引的前缀而不是索引中列的随机分类来使用索引中列的子集。
同样重要的是要注意,表上的索引越多,对该表的写入速度就越慢。只需考虑Oracle必须做的所有工作来更新表以及与之关联的所有索引。 BITMAP索引可能会产生更大的影响。
作为最后一点,EXPLAIN PLAN是你的朋友。如果您发现在大型表上执行全表扫描的常用查询,则索引可能是有序的。
答案 2 :(得分:1)
您的疑问。
您必须查看或更好地了解客户端应用代码,以查看最常使用的字段和/或存在性能问题。如果您的应用尚未构建,请考虑如何使用数据。例如;如果它是一个将大量用于报告的表,并且您有一个日期时间字段,那么您很可能需要该字段上的索引(复合与否)。
答案 3 :(得分:0)
经验法则是在外键上创建索引(PK通常会自动创建索引),联接中涉及的字段,where子句或排序。索引有一个插入成本,所以不要无所事事地创建它们。选择最常用的内容和运行时间最长的查询,以查看可能需要索引的位置。检查查询执行计划(不同的数据库调用此内容不同但所有方法都可以查看查询将如何使用索引)以查看索引是否在创建后使用。没有使用的索引只是添加插入和删除时间而在选择时间内没有相应的改进。
答案 4 :(得分:0)
完全取决于您对表运行的查询。
可能的候选人包括:
请不要认为你应该在一个表上创建一大堆索引,每个索引都在一个字段上。我看到了很多,而且它几乎总是错误的答案。一些额外的考虑因素:
答案 5 :(得分:0)
这里有一些好主意。特别注意有性能问题的查询,并尝试以高选择性创建索引。
另外,监控索引使用情况并不是一个坏主意:
ALTER INDEX <index> MONITORING USAGE;
您可以定期检查v $ object_usage.used的值,以查看自启用监控后是否曾访问过索引:
SELECT i.table_name, i.index_name, i.tablespace_name, bytes/1000000 mb, u.used
FROM dba_indexes i JOIN dba_segments ON (i.index_name = segment_name)
LEFT OUTER JOIN v$object_usage u ON (i.index_name = u.index_name)
WHERE i.owner = <schema>
AND NVL(USED,'NO') = 'NO'
AND i.table_name = <table of interest>
ORDER BY bytes DESC;
我已经能够用这提供的信息修剪几个索引。