oracle索引的三个问题
索引(索引)是常见的数据库对象。它的设置是好是坏,它的使用是否得当,对数据库应用程序和数据库的性能有很大的影响,虽然有很多关于索引使用的数据,DBA和开发人员经常处理,但我发现很多人仍然误解了它。因此,在使用中常见的问题有三个方面的问题。在所有的例子,数据库为Oracle 8.1.7 OPS对HP的N系列。这些例子都是真实的数据。读者不必关注具体的数据大小,但在使用不同的方法后要注意数据的比较,本文基本上是陈词滥调,但作者试图通过实例来真正了解事物的关键。
首先,指数并不总是最好的选择。
如果发现Oracle被索引,则不使用索引,而这不是Oracle优化器的错误。在某些情况下,Oracle选择全表扫描(全表扫描)而不是索引扫描(索引扫描):
1。表不做统计或统计过时,导致Oracle误判。
2。根据记录的数目和表中数据块的个数,实际全表扫描比索引扫描更快。
对于第一种情况,最常见的示例是以下SQL语句:
在做统计,它使用全表扫描,需要读6000个以上的数据块(数据块8K)。统计后,使用索引(快速全扫描),只需要读取450个数据块,但统计数据不好,也导致Oracle不使用索引。
第二种情况复杂得多。一般的概念是,该指数比表要快,而且很难理解全表扫描比索引扫描的速度更快。为了澄清这个问题,我们首先介绍Oracle的重要数据进行评估时,使用索引的代价(成本):CF(聚类因子)和FF(过滤因子)。
CF,通俗地说,是读入一个索引块,对应读取多少个数据块。
FF,由SQL语句选择的结果集,占数据总量的百分比。
近似公式是:FF(CF +索引块数),因此估计一个查询,如果使用索引,它将需要读取数据块的数量。需要读取更多的数据块,然后成本越大,Oracle更可能选择不使用索引。(完整的表扫描读取数据块的数量等于表的数据块的实际数量)
本文的核心是CF可能大于数据blocks.cf实际人数指标数据排列,通常在刚建立的指标,已经在记录表的索引关系,CF很小;表中大量的插入,经过修改的关系更加混乱,越来越多的,在这一点上,DBA需要重新组织索引。
如果SQL语句以前已经使用索引,那么很长一段时间后它将不再使用。一种可能性是CF变得太大,需要重新组织索引。
FF是基于统计的Oracle进行估计。例如,mytables表有32万行,其主键不存在最小值是1,最大值为409654,和下面的SQL语句是:
SQL语句看起来类似于同一语句,对于Oracle是非常不同的,因为前者的FF是100%,后者的FF可能只有1%,如果CF大于数据块的实际数量,Oracle可能选择不同的优化方法。事实上,我们数据库上的测试验证了我们的预测。下面是他们的解释计划:在HP执行时
第一句:
已经选了325917行。
第二句:
很明显,第一句不使用索引,和第二句对主要关键指标pk_mytables使用巨大的影响。因此,当我们编写SQL语句时,如果预先估计FF,几乎可以看出Oracle是否使用索引。
{分页}
第二,指数也是好的和坏的。
索引有B树索引、位图索引、反向B树索引等,最常用的是B树索引,B的全称是平衡的,它的意思是,从树根到任何叶子,都经过这个级别。指数一样,只能有一个字段(单栏),也可以有多个字段(复合),最多32个字段,8i还支持基于函数的索引。许多开发人员倾向于使用索引单b树。
所谓指数的质量指的是:
1、多指标、更好。特别是,大量的索引或几乎未使用的指标对系统的损害,OLTP系统性能指标小于5每桌,和一个SQL,Oracle不使用5个以上的指标。
2,在许多情况下,单列索引不如复合索引那么高效。
3,多表连接的字段,加上索引,将是有用的。
那么,在什么情况下,单一指标比综合指数效率低显而易见的一点是,当SQL语句中查询的所有列出现在复合索引中时,Oracle可以通过查询索引块获得所有数据,这比使用多个单列索引快得多(此时,这种优化称为索引访问路径)。
还有什么呢让我们看一个例子。
执行下面的语句(HP Oracle 8.1.7):
在开始的时候,我们有两单柱指标:i_mytabs1(冷),i_mytabs2(合同签发日期),以下是执行:
如您所见,它读取7000个数据块以获得所查询的6000多行。
现在,删除这两单列索引,添加复合指数i_mytabs_test(冷,合同签发日期),并重新执行它。结果如下:
如您所见,这次只读取了300个数据块。
7000到300,在这个例子中,这是单列索引与复合索引的价格之比。这个例子表明,在许多情况下,单列索引不如复合索引有效。
可以说,在设置索引方面有很多工作要做,正确设置索引需要对应用程序进行全面的分析。
十三
{分页}
第3章,指数又是好的,不是虚荣的。
除了前面所说的,在下一页的伪{ 1 } { 2 }上所看到的Oracle教程是Oracle索引的三个问题。您设置了一个非常好的索引,任何傻瓜都知道它应该被使用,但是Oracle不需要它。要做的第一件事是扫描SQL语句。
要使用索引,Oracle有一些最基本的条件:
1,WHERE子句中的这个字段必须是复合索引的第一个字段。
2,WHERE子句中的这个字段不应涉及任何形式的计算。
具体来说,假设根据f1、F2和F3的顺序建立索引。现在有一个SQL语句的WHERE子句,F2 =:var2,因为F2不是索引的第一场,不能使用该指标。
第二个问题非常严重,下面是几个实际系统的例子:
上面的例子可以很容易地改进。请注意,这样的语句每天都在我们的系统中运行,消耗我们有限的CPU和内存资源。
除了我们必须记住的两条原则中的1, 2条之外,我们还应该熟悉各种操作符对Oracle索引使用的影响。在这里,我只讨论哪些操作或操作字符将显式地(明确地)阻止Oracle使用索引:
1,如果f1和F2是同一表的两个字段,则f1 > F2,f1 = F2,f1
2,f1是null,f1不是NULL,f1不在,F1!=。
3,不存在
4,在某些情况下,F1不会被编入索引;
这些操作不可能完成,只是为了避免它。例如,如果您发现SQL中的操作不使用索引,您可以将操作更改为比较操作+联合所有。我在实践中发现,这非常有效。
但是,Oracle是否真的使用了索引,索引是否真的有效,或者它是否必须在实地测试,在将它编写到应用程序之前对所编写的复杂SQL作出解释是合理的。解释将获得Oracle对SQL(计划)的解析,我们可以清楚地看到Oracle是如何优化SQL的。
如果你经常做解释,你会发现它是不爱写复杂的SQL的一个很好的习惯,因为太复杂的SQL语句的解析方案往往不满意。事实上,拆卸复杂的SQL有时可以大大因为它可以很好的优化提高效率。当然,这是题外话。
上一页
{ 1 } { 2 }的最后一页