有個空間

          有個標題

          ORA-01795,in和exists性能

          今天,客戶那邊出來一個問題,出現(xiàn)"ORA-01795:列表中的最大表達式數(shù)為1000 "異常。

          sql文是這樣的:
          1 select ENAME
          2   from  VIP_EMP
          3  where GROUP_ID = '0001'
          4    and SUBGROUP_ID = '000101'
          5    and VIPNO  in
          6        (select EMPNO
          7           from EMP
          8          where EMPTYPE = 'VIP')

          調(diào)查后發(fā)現(xiàn),在"PLSQL Developer"和"sqldeveloper"中直接運行時,都不會報錯,雖然上面子查詢的記錄大于1000條。
          然后,嘗試將子查詢改成拼接一個大于1000項的數(shù)組,結(jié)果如愿出現(xiàn)"ORA-01795"異常。
          猜想,開發(fā)這邊的數(shù)據(jù)庫可能將上述sql文優(yōu)化了,但客戶數(shù)據(jù)庫沒有經(jīng)編譯器優(yōu)化,所以出異常。

          可能優(yōu)化成了以下的形式:
          1 select e1.ENAME from VIP_EMP e1, (select EMPNO from EMP where EMPTYPE= 'VIP') e2 
          2    where e1.VIPNO = e2.EMPNO;
          2        and e1.GROUP_ID = '0001'
          2        and e1.SUBGROUP_ID = '000101'

          最終,個人修改意見是,修改成兩張表鏈結(jié)的形式,即優(yōu)化以后的樣子。這樣修改,性能先不管,至少不會出現(xiàn)異常。

          還有個尾巴留下來了,就是In的性能問題。現(xiàn)將網(wǎng)上查到的東西貼出來。

          1.in和exists的性能差別

           在where子句中可以使用兩種格式的子查詢。

          第一種格式是使用IN操作符,第二種格式是使用EXIST操作符。

          修改的exists形式:

          1  select e1.ENAME
          2    from VIP_EMP e1
          3   where e1.GROUP_ID = '0001'
          4     and e1.SUBGROUP_ID = '000101'
          5     and exists (select 0
          6            from EMP e2
          7           where e2.EMPTYPE = 'VIP'
          8             and e2.EMPNO = e1.VIPNO)

          用第一種:Oracle系統(tǒng)在執(zhí)行IN子查詢時,首先執(zhí)行 子查詢,并將獲得的結(jié)果列表存放在在一個加了索引的臨時表中。在執(zhí)行子查詢之前,系統(tǒng)先將主查詢掛起,待子查詢執(zhí)行完畢,存放在臨時表中以后再執(zhí)行主查 詢。

          用第二種:通過使用 EXIST,Oracle系統(tǒng)會首先檢查主查詢,然后運行子查詢直到它找到第一個匹配項,這就節(jié)省了時間。這也就是使用EXISTS比使用IN通常查詢速度快的原因。子查詢以‘select 'X'開始。運用EXISTS子句不管子查詢從表中抽取什么數(shù)據(jù)它只查看where子句。這樣優(yōu)化器就不必遍歷整個表而僅根據(jù)索引就可完成工作(這里假定 在where語句中使用的列存在索引)。

          相對于IN子句來說,EXISTS使用相連子查詢,構(gòu)造起來要比IN子查詢困難一些。


          同時應盡可能使用NOT EXISTS來代替NOT IN,盡管二者都使用了NOT(不能使用索引而降低速度),NOT EXISTS要比NOT IN查詢效率更高。

          比較一致的看法是:為了確定在基于規(guī)則的最優(yōu)化中,哪一種子句性能更佳,不妨考慮一下,與外部查詢相比,內(nèi)部查詢會返回多少行記錄。許多情況下,EXISTS的表現(xiàn)更突出, 這是因為,它需要你指定一個加入條件,這就可以調(diào)用一個INDEX掃描。盡管如此,如果該查詢的結(jié)果很小的話,IN常常表現(xiàn)得更好。你通常都愿意運行那些 能首先返回較少的結(jié)果的查詢。

          千言萬語總結(jié)成一句話:如果內(nèi)表大,外表小用exists或not exists,反之用in或not in;

          個人推薦還是用兩張表鏈結(jié)的形式,直觀簡單,至少不會出現(xiàn)ORA-01795異常


          posted on 2009-09-07 13:54 游雯 閱讀(4959) 評論(0)  編輯  收藏 所屬分類: Java技術(shù)

          主站蜘蛛池模板: 肇源县| 禄丰县| 长丰县| 贺州市| 梅河口市| 土默特右旗| 始兴县| 双城市| 天柱县| 海丰县| 彰化县| 汾阳市| 于田县| 普陀区| 彭阳县| 盘锦市| 长泰县| 浏阳市| 荣昌县| 龙川县| 衡东县| 临海市| 永修县| 内丘县| 隆林| 清镇市| 南川市| 黑龙江省| 永泰县| 平陆县| 师宗县| 砚山县| 涞源县| 贺州市| 繁峙县| 沭阳县| 沾益县| 吴堡县| 太原市| 嘉兴市| 大余县|