最重要一點,ORACLE的高速緩衝是全字符匹配的,什麼意思呢,看下面三個select
select *fromtableA;
--No.2
select *FromtableA;
--No.3
select *from tableA;
這三個語句乍一看是一樣的,但是高速緩存是不認的,是全字符匹配的,索引在高速緩存裏會存儲三條不同的語句,說到這裏,又引出一個習慣,就是要保持良好的編程習慣,這個很重要
ORACLE多表優化我積累了一些,都是常用的,介紹下
一、FROM子句後面的表順序有講究
先說爲啥,ORACLE在解析sql語句的時候對FROM子句後面的表名是從右往左解析的,是先掃描最右邊的表,然後在掃描左邊的表,然後用左邊的表匹配數據,匹配成功後就合併。所以,在對多表查詢中,一定要把小表寫在最右邊,爲什麼自己想想就明白了。例如下面的兩個語句:
select count(*)from tableA, tableB;
--No.2 執行速度百秒甚至更高
select count(*)from tableB, tableA;
這個估計很多人都知道,但是要確認非常有用。
還有一種是三張表的查詢,例如
上面中tableA爲交叉表,根據oracle對From子句從右向左的掃描方式,應該把交叉表放在最末尾,然後纔是最小表,所以上面的應該這樣寫
--tabelB b 100w
--tableC c 1w
select count(1)from tableB b ,tableC c ,tableA a where a.id=b.id and a.id=c.id;
這種寫法對大數據量會非常有用,大家謹記,也是很常用的。
二、Where子句後面的條件過濾有講究,ORACLE對where子句後面的條件過濾是自下向上,從右向左掃描的,所以和From子句一樣一樣的,把過濾條件排個序,按過濾數據的大小,自然就是最少數據的那個條件寫在最下面,最右邊,依次類推,例如
select *from tableA a where
a.id>500
and a.lx ='2b'
and a.id < (select count(1)from tableA where id=a.id)
--No.2 性能高
select *from tableA a where
a.id < (select count(1)from tableA where id=a.id)
and a.id>500
and a.lx ='2b'
三、使用select的時候少用*,多敲敲鍵盤,寫上字段名吧,因爲ORACLE的查詢器會把*轉換爲表的全部列名,這個會浪費時間的,所以在大表中少用
四、充分利用rowid ,可以用rowid來分頁,刪除查詢重複記錄,很強大的,給兩個例子:
select *from tableA a wherea.rowid>=(select min(rowid) from tableB b wherea.column=b.column)
--oracle刪除重複記錄
delete from tableA a where a.rowid>=(select min(rowid) from tableB b wherea.column=b.column)
--分頁 start=10 limit=10
--end 爲 start + limit
--1.查詢要排列的表A
--2.查詢A表的Rownum找出小於end的數據組成表B
--3.查詢B表通過rownum找出大於start的數據完成
--簡單的說先根據end值過濾數據,然後在根據start過濾數據
SELECT *FROM
(SELECT a.*,ROWNUM rn FROM (SELECT * FROM uim_serv_file_data ORDER BY OUID) awhere ROWNUM<=20) b
where rn>10 order by ouid desc
五、存儲過程中需要注意的,多用commit了,既可以釋放資源,但是要謹慎。
六、減少對數據庫表的查詢,這個很重要,能減少就減少,因爲在執行語句的時候oracle會做很多初始工作。
七、少用in,多用exists來代替
--NO.1 IN的寫法SELECT *FROM TABLEA A WHERE
A.ID IN (SELECT ID FORM TABLEB B WHERE B.ID>1)
--NO.2 exists 寫法
SELECT *FROM TABLEA A WHERE
EXISTS (SELECT 1FROM TABLEB B WHEREA.ID=B.ID AND B.ID>1)