Oracle SQL建立有效索引减少回表

上一篇 / 下一篇  2012-09-28 09:47:50 / 个人分类:数据库

i)L;[%DG#j(_4UYsk0  回表:在数据中,当查询数据的时候,在索引中查找索引后,获得该行的rowid,根据rowid再查询表中数据,就是回表。51Testing软件测试网zR1D/xg

9a!{z&S9S&K0  在数据库中,数据的存储都是以块为单位的,称为数据块,表中每一行数据都有唯一的地址标志ROWID。每次使用SQL进行查询的时候,都要扫描数据块,找到行所在的ROWID,再扫描该表的数据块。回表将会导致扫描更多的数据块。

V{ z7i9@ NE:MI w0

7g\n0FL-x ]0  例如:SELECT a,b,cFROM TEST_DB WHERE b=1

(H };i2Q0HPZO_0

|/cQ1G@7V)t1b0  在该查询语句执行的时候,可分为两种情况:

R#j na)_%S0

%dWz#wF[.T0  A、在b上没有建立索引51Testing软件测试网]?X8R1c:B\Hp/b t

51Testing软件测试网6ZSEe3P/^)]r\/uq'J

  如果在b上没有建立索引,那么该条SQL语句执行时,要进行全表扫描,扫描所有该表中的数据块。从该数据块中找到记录,并进行过滤。在没有索引时,查找数据会导致扫描表中所有数据块,性能较低。51Testing软件测试网 @v~|1A(f?@

^gMzYub6\9j0  B、在b上建立索引

P(Z^7S3N/g a qgfN0

%Alz&w)K!N0   如果在b上建立索引,那么在执行该条SQL语句时,先进行索引扫描,在索引中找到b=1所在的位置(一般只需要扫描3个块数据即可),获得改行的 ROWID,根据其ROWID再查询数据(回表),如果所查找的数据量较少,则回表次数就少。如上面的例子,要查询的数据只有b在索引中,a并不在索引 中,那么就要回表一次查询a;如果a也在索引中,那么就不需要回表。

&D*H3{8|7}0

2J-xsJao.\-V0  在数据库查询中,需要用到回表的地方很多,如分页查询。一般要竟量在索引上分页,然后返回ROWID,在通过ROWID进行回表查询。

s.S+K1tib9f3J4|0P051Testing软件测试网l)g4G'HA!G5n ^#Z~

   如分页语句: SELECT *  FROM  ( SELECT ROW_NUMBER OVER (ORDER BY A ) RN,T.* FROM  TABLE  T  WHERE B=?  AND C=? ) WHERE  RN>=1 AND  RN <=20

] OkJ e#m6F%`051Testing软件测试网l%U,Yx C

  在该分页查询语句中,我们建立B,C,A的索引,那么查询时,步骤如下:

6rcRd BhG?0

3a-A'Y;\:G0  1、先查询内层语句 SELECT *  FROM  TABLE T  WHERE  B=?  AND  C=?,假设返回1000行数据。

l`f;WD _~0

%gY+W9emx0   2、通过索引找到这1000行数据的ROWID,由于索引时连续的,所以假设这1000行数据的索引分布在3个数据块中,一般需要读取6个数据块。再根 据ROWID取回表查询数据,最差的情况是这1000行数据分布在1000个数据块中,则需要读取1000块。那么总共需要读取的数据块区为1006块。

6~@`%r:t Q;}f051Testing软件测试网1dp*L4r|)L"V#WH

  如果我们换另外一种写法:51Testing软件测试网k(~3Z4g6i~$^5C

51Testing软件测试网}i5Tr,uVI

   SELECT  * FROM  TABLE  T, (SELECT  RID  FROM (SELECT ROWID  RID, ROW_NUMBER  OVER(ORDER BY  A)  RN FROM  TABLE  WHERE B=?  AND  C=?) WHERE  RN >1 AND  RN<=20 )  TMP WHERE  TMP.RID = T.ROWID51Testing软件测试网;cC T+Px!^A$N4C|

51Testing软件测试网CyN.A-n Q

  在 例子中,最里层的SELECT RID  FROM (SELECT  ROWID RID, ROW_NUMBER  OVER(ORDER  BY A)  RN  FROM TABLE  WHERE  B=? AND  C=?) WHERE  RN >1 AND  RN<=20,可以全部在索引中获取到数据,和上面一样,也差不多为6数据块。分页之后,只有20行数据,在更具这20行的ROWID回表查询数 据,最坏的情况是20行都在20个不同块中,那么总共也只扫描26块数据块。

0|S B:M jhz051Testing软件测试网jf5_5@R8r#V:H

  因此,有效的利用索引,可以减少回表的次数,大大提升SQL性能。

_b ok3e v m B0

TAG:

 

评分:0

我来说两句

Open Toolbar