sql程式設計注意事項
1 in操作符
用in寫出來的sql的優點是比較容易寫且清晰易懂,這比較適合現代軟體開發的風格。
但是用in的sql效能總是比較低的,從oracle執行的步驟來分析用in的sql與不用in的sql有以下區別:
oracle試圖將其轉換成多個表的連線,如果轉換不成功則先執行in裡面的子查詢,再查詢外層的表記錄,如果轉換成功則直接採用多個表的連線方式查詢。由此可見用in的sql至少多了乙個轉換的過程。一般的sql都可以轉換成功,但對於含有分組統計等方面的sql就不能轉換了。
推薦方案:在業務密集的sql當中盡量不採用in操作符。
2 not in操作符
此操作是強列推薦不使用的,因為它不能應用表的索引。
推薦方案:用not exists 或(外連線+判斷為空)方案代替
3 <>操作符(不等於)
不等於操作符是永遠不會用到索引的,因此對它的處理只會產生全表掃瞄。
推薦方案:用其它相同功能的操作運算代替,如:
a<>0 改為a>0 or a<0
a<>』』 改為
a>』』
4 is null或is not null操作(判斷字段是否為空)
判斷字段是否為空一般是不會應用索引的,因為b樹索引是不索引空值的。
推薦方案:
用其它相同功能的操作運算代替,如
a is not null 改為a>0 或a>』』等。
不允許欄位為空,而用乙個預設值代替空值,如業務申請中狀態字段不允許為空,預設為申請。
建立位圖索引(有分割槽的表不能建,位圖索引比較難控制,如字段值太多索引會使效能下降,多人更新操作會增加資料塊鎖的現象)
5 > 及< 操作符(大於或小於操作符)
大於或小於操作符一般情況下是不用調整的,因為它有索引就會採用索引查詢,但有的情況下可以對它進行優化,如乙個表有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的記錄索引。
6 like操作符
like操作符可以應用萬用字元查詢,裡面的萬用字元組合可能達到幾乎是任意的查詢,但是如果用得不好則會產生效能上的問題,如like 『%5400%』 這種查詢不會引用索引,而like 『x5400%』則會引用範圍索引。
7 union操作符
union在進行表鏈結後會篩選掉重複的記錄,所以在表鏈結後會對所產生的結果集進行排序運算,刪除重複的記錄再返回結果。實際大部分應用中是不會產生重複的記錄,最常見的是過程表與歷史表union。如:
select * from gc_dfys
union
select * from ls_jg_dfys
這個sql在執行時先取出兩個表的結果,再用排序空間進行排序刪除重複的記錄,最後返回結果集,如果表資料量大的話可能會導致用磁碟進行排序。
推薦方案:採用union all操作符替代union,因為union all操作只是簡單的將兩個結果合併後就返回。
8 order by語句
order by 語句的執行效率很低,因為它要排序。應避免在order by 字句中使用表示式。
9 where後面的條件順序影響
where子句後面的條件順序對大資料量表的查詢會產生直接的影響,如
select * from zl_yhjbqk where dy_dj = '1kv以下' and xh_bz=1
select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1kv以下
'以上兩個sql中dy_dj(電壓等級)及xh_bz(銷戶標誌)兩個欄位都沒進行索引,所以執行的時候都是全表掃瞄,第一條sql的dy_dj = '1kv以下'條件在記錄集內比率為99%,而xh_bz=1的比率只為0.5%,在進行第一條sql的時候99%條記錄都進行dy_dj及xh_bz的比較,而在進行第二條sql的時候0.5%條記錄都進行dy_dj及xh_bz的比較,以此可以得出第二條sql的cpu佔用率明顯比第一條低。
10查詢表順序的影響
oracle的解析器按照從右到左的順序處理from子句中的表名,因此from子句中寫在最後的表(基礎表driving table)將被最先處理。 在from子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表。當oracle處理多個表時, 會運用排序及合併的方式連線它們。首先,掃瞄第乙個表(from子句中最後的那個表)並對記錄進行排序,然後掃瞄第二個表(from子句中最後第二個表),最後將所有從第二個表中檢索出的記錄與第乙個表中合適記錄進行合併。
如果有3個以上的表連線查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表。
11 where子句中的連線順序
oracle採用自下而上的順序解析where子句,根據這個原理,表之間的連線必須寫在其他where條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在where子句的末尾。
12避免使用select *
當你想在select子句中列出所有的column時,使用動態sql列引用『*』 是乙個方便的方法。不幸的是,這是乙個非常低效的方法。實際上,oracle在解析的過程中, 會將』*』 依次轉換成所有的列名,這個工作是通過查詢資料字典完成的, 這意味著將耗費更多的時間。
13 以下情況將不會使用索引
13.1 字串連線
(||)
select * from employee where name||department=』zyzbioinfo』;
select * from employee where name=』zyz』 and department=』bioinfo』;
這兩個查詢,第二句比第一句會快,因為對於有連線運算子』||』的查詢,oracle優化器是不會使用索引的。
13.2 『%』萬用字元在第乙個字元的
當萬用字元出現在搜尋詞首時,oracle優化器不使用索引
13.3 存在資料型別**轉換
隱含的型別轉換可能會使oracle優化器忽略索引。
13.4 列上有數**算
如:select * from staff_member where salary*2<10000;
13.5 索引列上使用函式
14多個索引情況下的選擇
當sql語句的執行路徑可以使用分布在多個表上的多個索引時,oracle會同時使用多個索引並在執行時對它們的記錄進行合併, 檢索出僅對全部索引有效的記錄。
在oracle選擇執行路徑時,唯一性索引的等級高於非唯一性索引。 然而這個規則只有
當where子句中索引列和常量比較才有效。如果索引列和其他表的索引類相比較。 這種子句在優化器中的等級是非常低的。
如果不同表中兩個相同等級的索引將被引用,from子句中表的順序將決定哪個會被率先使用。from子句中最後的表的索引將有最高的優先順序。
如果相同表中兩個想同等級的索引將被引用,where子句中最先被引用的索引將有最高的優先順序。
SQL 注意事項
選擇表名 配置ctrl 3 能夠select 桌 use nb go 物 storedprocedure dbo sp select 指令碼日期 05 28 2015 21 46 25 set ansi nulls on go set quoted identifier on go create p...
sql 注意事項
在 oracle 都是不等於號的意思。都可以使用。但是奇怪的是,我想拿出price 不是180000旳商品時 select id,name,from product where price 180000 執行這個語句是,price null 的記錄不出來,也就是拿不到price 是null的商品,必...
程式設計注意事項
1.動態輸出表頭或資料 每次輸出之前,請先清空表頭以及資料再新增。2.一般資料都要分頁,請直接加上分頁 3.重複性資料的校驗 介面接收資料 1.介面接收資料,一般型別接受 例如 string 列印日誌,之後再轉換成自己想要的格式json等。需求評審 問題一 大面問題 1.是什麼?2.怎樣玩?業務流程...