oracle 语法写法注意事项

SQL语法的写法注意[@more@]

1or请使用union all代替;

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

3in请使用exists代替;

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

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

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

7,在寫sqlwhere condition 時不要對columnfunction

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

原语句:

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 ,不使用functioncolumn

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,可試著用existsjoin的方式改寫

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

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

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

index不會被使用。

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

有興趣的話可以上網查:column histrogrambind varable peeking

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

且反而會更慢

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

转载于:http://blog.itpub.net/23307206/viewspace-1043069/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值