首先對數據的優化不能僅僅盯着SQL語句,首先要解決的就是對數據庫的設計,儘可能符合數據的三大範式再去考慮優化SQL語句。html
數據庫的三大範式能夠這樣來簡單理解:數據庫
第1規範:沒有重複的組或多值的列,這是數據庫設計的最低要求。緩存
第2規範:每一個非關鍵字段必須依賴於主關鍵字,不能依賴於一個組合式主關鍵字的某些組成部分,消除部分依賴,大部分狀況下,數據庫設計都應該達到第二範式。oracle
第3規範:一個非關鍵字段不能依賴於另外一個非關鍵字段。消除傳遞依賴,達到第三範式應該是系統中大部分表的要求,除非一些特殊做用的表。數據庫設計
一:SQL語句設計優化分佈式
1.外鍵約束會影響插入和刪除的性能,因此對一些表若是能夠沒有外鍵儘可能不要設置,若是對有些表中的數據有約束,最好在建表的SQL語句用描述完整性來實現,而不是用SQL程序中實現。性能
2.儘可能使用相同的或很是相似的SQL語句進行查詢,這樣不只充分利用SQL共享池中的已經分析的語法樹,要查詢的數據在SGA中命中的可能性也會大大增長。優化
3.SQL語句儘可能所有大寫,特別是表名和列名,尤爲是在使用SQL命令的緩存功能更加要統一大小寫。由於oracle 老是先解析SQL語句,把小寫的字母轉換成大寫的再執行。spa
4.根據緩存的特色,儘可能不要拼湊條件,而是使用佔位符.net
5.避免不帶任何條件的SQL語句的執行。沒有任何條件的SQL語句在執行時,一般要進行FTS,數據庫先定位一個數據塊,而後按順序依次查找其它數據,對於大型表這將是一個漫長的過程。
6.減小對數據庫的查詢次數,即減小對系統資源的請求,使用快照和顯形圖等分佈式數據庫對象能夠減小對數據庫的查詢次數。
7.注意組合主鍵的字段次序,對於組合主鍵來講,不一樣的字段次序的主鍵的性能差異可能會很大,通常應該選擇重複率低、單獨或者組合查詢可能性大的字段放在前面。
8.字段是數據庫最基本的單位,其設計對性能的影響是很大的。
A、數據類型儘可能用數字型,數字型的比較比字符型的快不少。
B、數據類型儘可能小,這裏的儘可能小是指在知足能夠預見的將來需求的前提下的。
C、 儘可能不要容許NULL,除非必要,能夠用NOT NULL+DEFAULT代替。
D、少用TEXT和IMAGE,二進制字段的讀寫是比較慢的,並且,讀取的方法也很少,大部分狀況下最好不用。
E、自增字段要慎用,不利於數據遷移。
9.索引
A、根據數據量決定哪些表須要增長索引,數據量小的能夠只有主鍵。
B、根據使用頻率決定哪些字段須要創建索引,選擇常常做爲鏈接條件、篩選條件、聚合查詢、排序的字段做爲索引的候選字段。
C、把常常一塊兒出現的字段組合在一塊兒,組成組合索引,組合索引的字段順序與主鍵同樣,也須要把最經常使用的字段放在前面,把重複率低的字段放在前面。
D、一個表不要加太多索引,由於索引影響插入和更新的速度。
10.建立視圖
二:操做符優化
一、IN
用IN寫出來的SQL的優勢是比較容易寫及清晰易懂,這比較適合現代軟件開發的風格。可是用IN的SQL性能老是比較低的,從ORACLE執行的步驟來分析用IN的SQL與不用IN的SQL有如下區別:
ORACLE試圖將其轉換成多個表的鏈接,若是轉換不成功則先執行IN裏面的子查詢,再查詢外層的表記錄,若是轉換成功則直接採用多個表的鏈接方式查詢。因而可知用IN的SQL至少多了一個轉換的過程。通常的SQL均可以轉換成功,但對於含有分組統計等方面的SQL就不能轉換了。在業務密集的SQL當中儘可能不採用IN操做符。
優化SQL時,常常碰到使用IN的語句,必定要用exists把它給換掉,由於Oracle在處理In時是按Or的方式作的,即便使用了索引也會很慢。
二、NOT IN
強列推薦不使用的,由於它不能應用表的索引。用NOT EXISTS或(外鏈接+判斷爲空)方案代替
三、IS NULL或IS NOT NULL操做 也是儘可能避免
四、>及 <操做符(大於或小於操做符)
大於或小於操做符通常狀況下是不用調整的,由於它有索引就會採用索引查找,但有的狀況下能夠對它進行優化,如一個表有100萬記錄,一個數值型字段 A,30萬記錄的A=0,30萬記錄的A=1,39萬記錄的A=2,1萬記錄的A=3。那麼執行A>2與A>=3的效果就有很大的區別了,由於A>2時ORACLE會先找出爲2的記錄索引再進行比較,而A>=3時ORACLE則直接找到=3的記錄索引。
用>=替代>
高效:
SELECT …FROM DEPARTMENTWHERE DEPT_CODE >=0;
低效:
SELECT*FROM EMPWHERE DEPTNO>3
二者的區別在於, 前者DBMS將直接跳到第一個DEPT等於4的記錄然後者將首先定位到DEPT NO=3的記錄而且向前掃描到第一個DEPT大於3的記錄.
五、LIKE操做符:儘可能使用 'aaa%' 而不是 '%aaa%'
六、用EXISTS替換DISTINCT:
七、用UNION替換OR (適用於索引列)
八、用IN來替換OR
九、當判斷真假是,若是帶and 或者 or :(當存在 「where 條件1 and 條件2」 時,數據庫先執行右邊的語句)
and儘可能把假的放到右邊(一個爲假就爲假) Or儘可能把爲真的放到右邊(一個爲真就爲真)
十、應儘可能避免在 where 子句中對字段進行表達式操做,這將致使引擎放棄使用索引而進行全表掃描。 如:
SELECT * FROM T1 WHERE F1/2=100
應改成:
SELECT * FROM T1 WHERE F1=100*2