oracle不空顺序输出,Oracle应用笔记
簡單整理自己的oracle筆記。
1、采用excel表格中的數據直接粘貼數據庫記錄中,默認會在后面加一個空格“”,操作完成后一定要記得對空格匹配然后修改一下。
2、查詢數據庫里的所有表結構,采用select * from dba_tables(sys登錄);
查看某個用戶所擁有的表:select * from all_tables WHERE owner='SCOTT' ;
或者?SELECT * FROM DBA_TABLES WHERE OWNER='SCOTT';
3、上午在PL/SQL dev中建表時提示ORA-00907:?缺失右括號,檢查sql腳本發現
eu_bctype ? ? ? ? ? INT(50)
Oracle中int為定長的類型,不能再規定其長度,需要改成number;
4、intersect運算
返回查詢結果中相同的部分既他們的交集
SQL> select * from abc
2??intersect
3??select * from abc2 ;
5、minus運算
返回在第一個查詢結果中與第二個查詢結果不相同的那部分行記錄,
即兩個結果的差集
SQL> select * from abc2
2??minus
3??select * from abc ;
6、TO_CHAR格式化小數點輸出
select To_char(sum(score),9999999.99)from score;
7、有很多種方法可以用來找出哪些SQL語句需要優化,但是很久以來,最簡單的方法都是分析保存在V$SQL視圖中的緩存的SQL信息。通過V$SQL視圖,可以確定具有高消耗時間、CUP和IO讀取的SQL語句
7.1查看總消耗時間最多的前10條SQL語句
select *
from (select v.sql_id,
v.child_number,
v.sql_text,
v.elapsed_time,
v.cpu_time,
v.disk_reads,
rank() over(order by v.elapsed_time desc) elapsed_rank
from v$sql v) a
where elapsed_rank <= 10;
7.2查看CPU消耗時間最多的前10條SQL語句
select *
from (select v.sql_id,
v.child_number,
v.sql_text,
v.elapsed_time,
v.cpu_time,
v.disk_reads,
rank() over(order by v.cpu_time desc) elapsed_rank
from v$sql v) a
where elapsed_rank <= 10;
7.3查看消耗磁盤讀取最多的前10條SQL語句
select *
from (select v.sql_id,
v.child_number,
v.sql_text,
v.elapsed_time,
v.cpu_time,
v.disk_reads,
rank() over(order by v.disk_reads desc) elapsed_rank
from v$sql v) a
where elapsed_rank <= 10;
8、oracle優化操作
1.不用“<>”或者“!=”操作符。對不等于操作符的處理會造成全表掃描,可以用“”代替
不等于操作符是永遠不會用到索引的,因此對它的處理只會產生全表掃描。推薦方案:用其它相同功能的操作運算代替,
如: 1)a<>0 改為 a>0 or a<0
2)a<>’’ 改為 a>’’
2. 選擇最有效率的表名順序(只在基于規則的優化器中有效):
ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最后的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個表的情況下,你必須
選擇記錄條數最少的表作為基礎表。如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表.
3.WHERE子句中的連接順序
ORACLE采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾.
4.SELECT子句中避免使用 ‘ * ‘
ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間
5.減少訪問數據庫的次數:
ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變量 , 讀數據塊等;
6.在SQL*Plus , SQL*Forms和Pro*C中重新設置ARRAYSIZE參數, 可以增加每次數據庫訪問的檢索數據量 ,建議值為200
7.使用DECODE函數來減少處理時間:
使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表.DECODE(input_value,value,result[,value,result…][,default_result]);
9.刪除重復記錄:
最高效的刪除重復記錄方法 ( 因為使用了ROWID)例子:
DELETE ?FROM ?EMP E ?WHERE ?E.ROWID > (SELECT MIN(X.ROWID)
FROM ?EMP X ?WHERE ?X.EMP_NO = E.EMP_NO);
10.用TRUNCATE替代DELETE:
當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復的信息. 如果你沒有COMMIT事務,ORACLE會將數據恢復到刪除之前的狀態(準確地說是
恢復到執行刪除命令之前的狀況) 而當運用TRUNCATE時, 回滾段不再存放任何可被恢復的信息.當命令運行后,數據不能被恢復.因此很少的資源被調用,執行時間也會很短. (譯者
按: TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML)
11.用Where子句替換HAVING子句:
避免使用HAVING子句, HAVING 只會在檢索出所有記錄之后才對結果集進行過濾. 這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的
開銷. (非oracle中)on、where、having這三個都可以加條件的子句中,on是最先執行,where次之,having最后,因為on是先把不符合條件的記錄過濾后才進行統計,它就可
以減少中間運算要處理的數據,按理說應該速度是最快的,where也應該比having快點的,因為它過濾數據后才進行sum,在兩個表聯接時才用on的,所以在一個表的時候,就
剩下where跟having比較了。在這單表查詢統計的情況下,如果要過濾的條件沒有涉及到要計算字段,那它們的結果是一樣的,只是where可以使用rushmore技術,而having
就不能,在速度上后者要慢如果要涉及到計算的字段,就表示在沒計算之前,這個字段的值是不確定的,根據上篇寫的工作流程,where的作用時間是在計算之前就完成的,而
having就是在計算后才起作用的,所以在這種情況下,兩者的結果會不同。在多表聯接查詢時,on比where更早起作用。系統首先根據各個表之間的聯接條件,把多個表合成一
個臨時表后,再由where進行過濾,然后再計算,計算完后再由having進行過濾。由此可見,要想過濾條件起到正確的作用,首先要明白這個條件應該在什么時候起作用,然后
再決定放在那里
12.使用表的別名(Alias):
當在SQL語句中連接多個表時, 請使用表的別名并把別名前綴于每個Column上.這樣一來,就可以減少解析的時間并減少那些由Column歧義引起的語法錯誤.
13.用EXISTS替代IN、用NOT EXISTS替代NOT IN:
在許多基于基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率. 在子查詢中,NOT IN子句將執
行一個內部的排序和合并. 無論在哪種情況下,NOT IN都是最低效的 (因為它對子查詢中的表執行了一個全表遍歷). 為了避免使用NOT IN ,我們可以把它改寫成外連接(Outer
Joins)或NOT EXISTS.
例子:
(高效)SELECT * FROM ?EMP (基礎表) ?WHERE ?EMPNO > 0 ?AND ?EXISTS (SELECT ‘X' ?FROM DEPT ?WHERE ?DEPT.DEPTNO = EMP.DEPTNO ?AND ?LOC = ‘MELB')
(低效)SELECT ?* FROM ?EMP (基礎表) ?WHERE ?EMPNO > 0 ?AND ?DEPTNO IN(SELECT DEPTNO ?FROM ?DEPT ?WHERE ?LOC = ‘MELB')
13.sql語句用大寫的;因為oracle總是先解析sql語句,把小寫的字母轉換成大寫的再執行
14.避免在索引列上使用NOT
我們要避免在索引列上使用NOT, NOT會產生和在索引列上使用函數相同的影響. 當ORACLE”遇到”NOT,他就會停止使用索引轉而執行全表掃描.
15.避免在索引列上使用計算.
WHERE子句中,如果索引列是函數的一部分.優化器將不使用索引而使用全表掃描.
舉例:
低效:
SELECT … FROM ?DEPT ?WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;
16.用>=替代>
高效:
SELECT * FROM ?EMP ?WHERE ?DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
兩者的區別在于, 前者DBMS將直接跳到第一個DEPT等于4的記錄而后者將首先定位到DEPTNO=3的記錄并且向前掃描到第一個DEPT大于3的記錄.
17.避免在索引列上使用IS NULL和IS NOT NULL
避免在索引中使用任何可以為空的列,ORACLE將無法使用該索引.對于單列索引,如果列包含空值,索引中將不存在此記錄. 對于復合索引,如果每個列都為空,索引中同樣不存在此記錄. 如果至少有一個列不為空,則記錄存在于索引中.舉例: 如果唯一性索引建立在表的A列和B列上, 并且表中存在一條記錄的A,B值為(123,null) , ORACLE將不接受下一條具有相同A,B值(123,null)的記錄(插入). 然而如果所有的索引列都為空,ORACLE將認為整個鍵值為空而空不等于空. 因此你可以插入1000 條具有相同鍵值的記錄,當然它們都是空! 因為空值不存在于索引列中,所以WHERE子句中對索引列進行空值比較將使ORACLE停用該索引.
低效: (索引失效)
SELECT … FROM ?DEPARTMENT ?WHERE ?DEPT_CODE IS NOT NULL;
高效: (索引有效)
SELECT … FROM ?DEPARTMENT ?WHERE ?DEPT_CODE >=0;
18.索引的弊端
a. 如果檢索數據量超過30%的表中記錄數.使用索引將沒有顯著的效率提高.
b. 在特定情況下, 使用索引也許會比全表掃描慢, 但這是同一個數量級上的區別. 而通常情況下,使用索引比全表掃描要塊幾倍乃至幾千倍!
19.可能引起全表掃描的操作
在索引列上使用NOT或者“<>”
對索引列使用函數或者計算
NOT IN操作
通配符位于查詢字符串的第一個字符
IS NULL或者IS NOT NULL
多列索引,但它的第一個列并沒有被Where子句引用
9、oracle SQL分頁查詢處理
分頁取11到20的記錄,兩種查詢方法,如下,
通過rownum,然后對記錄進行截取處理。
第一種的速度會比較快點,因為在tab1這層先過濾掉了一部分數據,第二種方法到最外層再進行處理
--分頁查詢1
SELECT TAB2.*
FROM (SELECT tab1.*, ROWNUM row_num
FROM (
--把需要分頁的sql直接放進來就行了
SELECT t.* FROM T_T_DEPT t
) TAB1
WHERE ROWNUM<21
) TAB2
WHERE TAB2.row_num >10
--分頁查詢2
SELECT TAB2.*
FROM (SELECT tab1.*, ROWNUM row_num
FROM (
--把需要分頁的sql直接放進來就行了
SELECT t.* FROM T_T_DEPT t
) TAB1
) TAB2
WHERE TAB2.row_num BETWEEN 11 AND 20
總結
以上是生活随笔為你收集整理的oracle不空顺序输出,Oracle应用笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql update nowait_
- 下一篇: python调用库函数用ecb模式加密图