2. 特別為計算建立函數索引
3. 將計算從等號左邊移到右邊
這是針對某些無(wú)心之失的糾正,把a*2>4 改為a>4/2;把TO_CHAR(zip) = '94002' 改為zip = TO_NUMBER('94002');
3.2 CBO與索引選擇性
建了索引也不一定會(huì )被Oracle用的,就像個(gè)挑食的孩子?;诔杀镜膬?yōu)化器(CBO, Cost-Based Optimizer),會(huì )先看看表的大小,還有索引的重復度,再決定用還是不用。表中有100 條記錄而其中有80 個(gè)不重復的索引鍵值. 這個(gè)索引的選擇性就是80/100 = 0.8,留意Toad里顯示索引的Selective和Cardinailty。實(shí)在不聽(tīng)話(huà)時(shí),就要用hints來(lái)調教。
另外,where語(yǔ)句存在多條索引可用時(shí),只會(huì )選擇其中一條。所以索引也不是越多越好:)
3.3 索引重建
傳說(shuō)中數據更新頻繁導致有20%的碎片時(shí),Oracle就會(huì )放棄這個(gè)索引。寧可信其有之下,應該時(shí)常alter index <INDEXNAME> rebuild一下。
3.4 其他要注意的地方
不要使用Not,如goods_no != 2,要改為
不要使用is null , 如WHERE DEPT_CODE IS NOT NULL 要改為
3.5 select 的列如果全是索引列時(shí)
又如果沒(méi)有where 條件,或者where條件全部是索引列時(shí),Oracle 將直接從索引里獲取數據而不去讀真實(shí)的數據表,這樣子理論上會(huì )快很多,比如
當order_no,order_time,shop_no 這三列全為索引列時(shí),你將看到一個(gè)和平時(shí)完全不同的執行計劃。
3.6 位圖索引
傳說(shuō)中當數據值較少,比如某些表示分類(lèi)、狀態(tài)的列,應該建位圖索引而不是普通的二叉樹(shù)索引,否則效率低下。不過(guò)看執行計劃,這些位圖索引鮮有被Oracle臨幸的。
4.減少查詢(xún)往返和查詢(xún)的表
這也是很簡(jiǎn)單的大道理,程序與Oracle交互的成本極高,所以一個(gè)查詢(xún)能完成的不要分開(kāi)兩次查,如果一個(gè)循環(huán)執行1萬(wàn)條查詢(xún)的,怎么都快不到哪里去了。
4.1 封裝PL/SQL存儲過(guò)程
最高級的做法是把循環(huán)的操作封裝到PL/SQL寫(xiě)的存儲過(guò)程里,因為存儲過(guò)程都在服務(wù)端執行,所以沒(méi)有數據往返的消耗。
4.2 封裝PL/SQL內部函數
有機會(huì ),將一些查詢(xún)封裝到函數里,而在普通SQL里使用這些函數,同樣是很有效的優(yōu)化。
4.3 Decode/Case
但存儲過(guò)程也麻煩,所以有case/decode把幾條條件基本相同的重復查詢(xún)合并為一條的用法:
4.4 一種Where/Update語(yǔ)法
5.其他優(yōu)化
5.1RowID和ROWNUM
連Hibernate 新版也支持ROWID了,證明它非常有用。比如號稱(chēng)刪除重復數據的最快寫(xiě)法:
6.終極秘技 - Hints
這是Oracle DBA的玩具,也是終極武器,比如Oracle在CBO,RBO中所做的選擇總不合自己心水時(shí),可以用它來(lái)強力調教一下Oracle,結果經(jīng)常讓人喜出望外。
如果開(kāi)發(fā)人員沒(méi)那么多時(shí)間來(lái)專(zhuān)門(mén)學(xué)習它,可以依靠Toad SQL opmitzer 來(lái)自動(dòng)生成這些提示,然后對比一下各種提示的實(shí)際效果。不過(guò)隨著(zhù)10g智能的進(jìn)化,hints的驚喜少了。
7. 找出要優(yōu)化的Top SQL
磨了這么久的槍?zhuān)绻也坏綌橙耸羌魫灥氖虑椤?br> 幸虧10g這方面做得非常好。進(jìn)入Web管理界面,就能看到當前或者任意一天的SQL列表,按性能排序。
有了它,SQL Trace和TKPROF都可以不用了。
聯(lián)系客服