我要两个表做关联查询/INSERT,其中
tab_big 一个很大的表
tab_sml 小表
请问:
select * 
from   tab_big a,tab_sml b
where  a.col_1=b.col_1
由于关联要很长时间,而且
我只想有很少的记录来做测试?所以我加入
and    rownum < 1000
有问题吗?
可是oracle还是执行全表扫描?
(与col_1有没有index无关)

解决方案 »

  1.   

    rownum是对查询结果的排序,所以还是先出查询结果集的
      

  2.   

    http://www.csdn.net/develop/read_article.asp?id=21371
      

  3.   

    rownum跟排序没有关系
    加上这个限制,肯定会快一些的
      

  4.   

    1.ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.例如:     表 TAB1 16,384 条记录     表 TAB2 1      条记录     选择TAB2作为基础表 (最好的方法)     select count(*) from tab1,tab2   执行时间0.96秒    选择TAB2作为基础表 (不佳的方法)     select count(*) from tab2,tab1   执行时间26.09秒    如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. 例如: 
       EMP表描述了LOCATION表和CATEGORY表的交集.
     SELECT * FROM LOCATION L ,       CATEGORY C,      EMP E WHERE E.EMP_NO BETWEEN 1000 AND 2000AND E.CAT_NO = C.CAT_NOAND E.LOCN = L.LOCN 将比下列SQL更有效率 SELECT * FROM EMP E ,LOCATION L ,       CATEGORY CWHERE  E.CAT_NO = C.CAT_NOAND E.LOCN = L.LOCNAND E.EMP_NO BETWEEN 1000 AND 2000 2.WHERE子句中的连接顺序. ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾. 例如: (低效,执行时间156.3秒)SELECT … FROM EMP EWHERE  SAL > 50000AND    JOB = ‘MANAGER’AND    25 < (SELECT COUNT(*) FROM EMP             WHERE MGR=E.EMPNO); (高效,执行时间10.6秒)SELECT … FROM EMP EWHERE 25 < (SELECT COUNT(*) FROM EMP             WHERE MGR=E.EMPNO)AND    SAL > 50000AND    JOB = ‘MANAGER’;
      

  5.   

    但是,从我观察的结果看,oracle是在执行一个table scan (full)啊?
    而且还有一个问题,where子句中的rownum是没有owner的,如不能知道 tab_big.rownum<1000!
      

  6.   

    http://www.csdn.net/develop/read_article.asp?id=21371标题     先排序还是先取值    black_snail(原作)  
      
    关键字     排序 前N条记录 
      
                                                              先排序还是先取值 题目:  MS SQLSERVER和ORACLE中取出表中按照某字段排序的前N条记录 这个题目看上去似乎那么简单, 两种数据库都提供ORDER BY 子句. 问题应该能够迎刃而解吧. 先试一下MS SQLSERVER是怎么做的:      use Northwind;create table TestSort (ID integer);insert into testSort values (3);insert into testSort values (1);insert into testSort values (4);insert into testSort values (2);select * from testSort;     -----------------------------------------ID          ----------- 3142(4 row(s) affected) 假设我们要取出按照ID排序的前三条记录:     select TOP 3 * from testSort order by ID ;        -----------------------------------------ID          ----------- 123(3 row(s) affected)   很简单,一句话就解决了. 再试一下ORACLE (这里用ORACLE9i)SQL>  create table TestSort ( ID number);Table created.SQL> insert into testSort values (3);1 row created.SQL> insert into testSort values (1);1 row created.SQL> insert into testSort values (4);1 row created.SQL> insert into testSort values (2);1 row created.SQL> commit;Commit complete.SQL> select * from testSort;ID----------         3         1         4         2 ORACLE没有MS SQLSERVER中取前N条记录的TOP语法. 但是有ROWNUM可以用来完成类似功能.  SQL> select * from TestSort where rownum <= 3 order by ID;ID----------         1         3         4 结果是不是有点出乎意料? 它并没有返回所要求的 1 , 2 , 3的结果 . ORACLE先根据rownum <=3的条件限制选取一个范围集合(3,1,4), 然后再在这个集合里进行排序. ORDER BY 子句是在合适的记录被取出后才起作用. 原来如此, 那么在ORACLE中如何才能实现这个功能呢? 通常我们可以采用这种办法:SQL> select * from (select * from TestSort order by ID) where rownum <=3;        ID----------         1         2         3     有点麻烦,不过也只能这样.     相同道理, 如果想从表中取出按照某字段排序前M到N条记录下面的ORACLE语句是最好的: SQL> select ID from     (       select ID , rownum as con from       (        select ID  from TestSort order by ID       )       where rownum <= 3   /*N值*/     )     where con >= 2;  /*M 值*/          ID----------         2         3 MS SQLSERVER中也可以用类似的思路解决此类问题.  当然你也可以用笨一点的办法, 比如用前N条记录的集合MINUS前M-1条记录的集合得到前M到N条记录集合. (有点象饶口令) , 不过MS SQLSERVER好象不支持MINUS之类的集合操作.  看来小小的一个排序取值问题还真不是那么简单呢 ! 
      

  7.   

    sorry,发错了
    迟些给个规则