SQL的问题又来了

[复制链接]
查看11 | 回复9 | 2008-2-13 12:43:03 | 显示全部楼层 |阅读模式
大家好,
我有下面一个sql,index已经都优化好了,我想取出结果集的前20行,并且还是在order by以后再取出
select * from

(select distinct T0.NSID as ColAlias1, T0.ID as ColAlias2, T0.VERSION as ColAlias3, T0.NAME as ColAlias4,

T1.NAME as ColAlias5, T0.INITIALEFFECTIVEDATE as ColAlias6, T0.TERMINATIONDATE as ColAlias7, T0.STATUS as ColAlias8,

T2.NAME as ColAlias9, T3.NAME as ColAlias10, T4.NAME as ColAlias11, T1.SHORTNAME as ColAlias12, T5.IDCONTRATEXTERNEFORMATRIB as ColAlias13,

T5.IDCONTRATEXTERNE as ColAlias14, T5.NUMIFIP as ColAlias15, T6.IDENTIFIANTORCODEAGENCE as ColAlias16

from AWFCONTRACT T0,

AWFPERSON T1,

AWFPRODUCT T2,

AWFISSUINGCOMPANY T3,

AWFHIERARCHY T4,

AWFCUSTOMIZATIONCONTRACTDA356F T5,

AWFBROKER T6,

AWFBROKERASSOCIATIONONCONTRACT T7,

AWFCONTRACTBROKERDATA T8,

AWFCONTRACTBROKERDATA_BROK54F6 T9

where ((((T0.BROKERDATA_NSID = T8.NSID) and (T0.BROKERDATA_ID = T8.ID) and (-T0.BROKERDATA_VERSION = T8.VERSION)))

and T8.NSID=T9.LONSID and T8.ID=T9.LOID and (((T7.BROKER_NSID = T6.NSID) and (T7.BROKER_ID = T6.ID)))

and (T7.ENDDATE >= :1) and (((T0.DATAEXTENSION_NSID = T5.NSID) and (T0.DATAEXTENSION_ID = T5.ID) and (-T0.DATAEXTENSION_VERSION = T5.VERSION)))

and (T0.STATUS:9))and ((T0.SUBSCRIBER_NSID=T1.NsId) and (T0.SUBSCRIBER_ID=T1.Id)) and ((T0.OFFEREDENTITY_NSID=T2.NsId) and (T0.OFFEREDENTITY_ID=T2.Id))

and ((T0.ISSUINGCOMPANY_NSID=T3.NsId) and (T0.ISSUINGCOMPANY_ID=T3.Id)) and ((T0.DISTRIBUTIONUNIT_NSID=T4.NsId)

and (T0.DISTRIBUTIONUNIT_ID=T4.Id)) and T9.NSId=T7.NSID and T9.Id=T7.ID and T9.Version= - T7.VERSION and (T1.H_ISCURVERS = 1)

and (T2.H_ISCURVERS = 1) and (T3.H_ISCURVERS = 1) and (T4.H_ISCURVERS = 1) and (T0.H_ISCURVERS = 1) and (T5.H_ISCURVERS = 1) and (T6.H_ISCURVERS = 1)

and (T0.H_ISKILLED = 0) and (T5.H_ISKILLED = 0) and (T6.H_ISKILLED = 0) and (T7.H_ISKILLED = 0) and (T8.H_ISKILLED = 0) and ( (T0.H_CLID=218109553)

or (T0.H_CLID=218956153) or (T0.H_CLID=218956154) or (T0.H_CLID=218113103) or (T0.H_CLID=218497198)) and (T5.H_CLID=219086894) and (T6.H_CLID=219086880)

Order By T0.NAME)
where ROWNUM <= 20;
oracle的工作原理是不是想把结果集放到一个临时表中进行order by,然后再取出前20行呢???
能不能有一个方法,在T0.NAME上建立个index,然后直接通过index取出前20行呢???
今天查了很久了,还是不清楚order by的工作原理,目的就是想避开取出结果集,而直接通过index取出前20行。。。
谢谢指点
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
自己来顶顶
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
数据在内存中可以order by,装不下的放在temp空间中吧
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
原帖由 laojiu9 于 2009-10-22 16:14 发表
数据在内存中可以order by,装不下的放在temp空间中吧

像我这种情况,有很多的join,oracle是要取出所有的要order by 的数据呢,还是要取出order by的数据的ROWID呢?
因为我主管跟我说,没有必要把数据都取出来进行order by啊,只需要取出rowid,然后order by好了rowid以后不就直接找到数据了吗
他还说如果是在order by的列上建立了index,就会提高效率的。但是我感觉就是如果有很多join,并且需要select不同表中的数据的时候,index的使用就与order by无关了呢。。。
不知道这样理解对么?
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
好你把你的这个sql的执行计划发出来一下
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
从你这几个帖子的东西回复来看,发现你们主管的水平不错
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
是否有用要看情况,这东西本来就没有个规律要具体发现,
举个简单例子
1.
select * from (
select * from a,b where a.column=b.columnorder by b.id desc) where rownum<11
假设a,b是主子表,a是主表,b是子表,column是主键,这时候走id的索引就很有用,因为从id里得到10个值后回表得到column都能从a取到符合的数据,这时候只要id索引里的10个值就ok
2.
相反如果a,b没有啥联系,那么走order by的索引可能效率更低
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
你的另一个贴子
http://www.itpub.net/thread-1228332-1-1.html
不是做了给做了实验吗
在order by上加索引只是避免了 排序
并没有避免全表扫描
具体是实现就是
1。没有索引的时候,全表扫描,排序
2。有索引的时候,通过全部扫描索引,通过索引对表进行了全表扫描,抽出的结果是排好序的
我理解就是用扫描索引的代价 来换取了排序。
具体那个更快没有研究过
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
我理解的应该先执行
select * from a,b where a.column=b.columnorder by b.id desc
然后再这个结果集里面把前10行拿出来
elect * from ( select a.empno,a.mgr mgrr ,b.mgr from emp a ,emp1 b where a.empno = b.empno order by a.empno) where rownum <5;
----------------------------------------------------------------------------------------------
| Id| Operation
| Name | Rows| Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT
|
| 4 | 156 | 3 (0)| 00:00:01 |
|*1 |COUNT STOPKEY
|
| | |
|
|
| 2 | VIEW
|
|14 | 546 | 3 (0)| 00:00:01 |
| 3 |TABLE ACCESS BY INDEX ROWID| EMP1 | 1 |26 | 1 (0)| 00:00:01 |
| 4 | NESTED LOOPS
|
|14 | 728 | 3 (0)| 00:00:01 |
| 5 |TABLE ACCESS BY INDEX ROWID| EMP|14 | 364 | 2 (0)| 00:00:01 |
| 6 | INDEX FULL SCAN | EMP_SAL| 4 | | 1 (0)| 00:00:01 |
|*7 |INDEX RANGE SCAN | EMP1_EMPNO | 1 | | 0 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
在id 1的时候才取的前面的10行
回复

使用道具 举报

千问 | 2008-2-13 12:43:03 | 显示全部楼层
在T0.NAME上建立个index,然后直接通过index取出前20行呢???
好像是可以的吧 INDEX FULL SCAN 好像就是。INDEX SCOPE SCAN 也是
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行