ITPub博客

首页 > 数据库 > Oracle > oracle 语法写法注意事项

oracle 语法写法注意事项

原创 Oracle 作者:alimzhao 时间:2010-12-14 08:03:39 0 删除 编辑
SQL语法的写法注意[@more@]

1,or请使用union all代替;

2,with...as...尽量使用交叉查询来替代,必要时也可以使用join代替;

3,in请使用exists代替;

4,时间上用>= and <=请使用between代替;

5,适当情况下增加trunk函数:

6,若用IN (SELECT ...)本身就會自動distinct了…語法中也不需要寫distinct…

7,在寫sql的where condition 時不要對column用function

(如下原语句和优化后的语句对比:

原语句:

AND (TO_DATE(WORK_DATE,'YYYY-MM-DD') BETWEEN NVL(:start_date, TO_DATE('2000-01-01','YYYY-MM-DD'))
AND NVL(:end_date, TO_DATE('2222-01-01','YYYY-MM-DD')))

优化后语句:

work_date between to_char(NVL(:start_date, TO_DATE('2000-01-01','YYYY-MM-DD')),'YYYY-MM-DD')
AND to_char(NVL(:end_date, TO_DATE('2222-01-01','YYYY-MM-DD'))),'YYYY-MM-DD')"

**Trunk的使用方法:

使用where to_date(to_char(a.in_process_time,'YYYY-MM-DD'),'YYYY-MM-DD') between :sdate and :edate的這種寫法是不會使用index的,因此我加了and a.in_process_time between trunc(:sdate) and trunc(:edate) + 0.99999進去做有效的table access

寫sql的原則 :

(1) column = value ,不使用function在column上

例1:
WORK_DATE||LPAD(TO_CHAR(WORK_TIME),2,'0')>='2010101200'
AND
WORK_DATE||LPAD(TO_CHAR(WORK_TIME),2,'0')<='2010101223'
這樣子寫不會使用index,可加入一個條件(access key),讓資料先縮小輸出的筆數

,再由原條件來filter,也就是改寫為以下寫法

WORK_DATE||LPAD(TO_CHAR(WORK_TIME),2,'0')>='2010101200'
AND
WORK_DATE||LPAD(TO_CHAR(WORK_TIME),2,'0')<='2010101223'

AND WORK_DATE BETWEEN '1010101200' AND '1010101223'

例2:

substr(abc,1,6) = 'avcdefg'

可改寫為

abc like 'avcdefg%'

(2) 減少使用in-List,可試著用exists或join的方式改寫

如果是not in則可用not exists來改寫

(3) or 有時不會使用index,可試著用union 或union all改寫

(4) 當查詢的資料量為總共資料的百分之四至五,才會用到index,所以若欄位中的值都一樣,或變異不大

建index不會被使用。

(5) 若資料分佈不均,則不要使用變數來當filter條件,這個道理我先前講過了,所以不再重覆說明。

有興趣的話可以上網查:column histrogram與bind varable peeking

此外…with … as …的語法,是用在一段需要大量sorting的sql,重覆被使用時再來使用,否則效果不會好到哪裡去

且反而會更慢

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23307206/viewspace-1043069/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2010-02-06

  • 博文量
    35
  • 访问量
    307133