亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

oracle SQL性能優化

系統 1784 0
我們要做到不但會寫SQL,還要做到寫出性能優良的SQL,以下為筆者學習、摘錄、并匯總部分資料與大家分享!
1 ????? 選擇 最有效率的表名 ( 只在基于 規則 化器中有效 )
ORACLE 的解析器按照從右到左的 FROM 子句中的表名, FROM 子句中寫在最后的表 ( driving table) 將被最先 理,在 FROM 子句中包含多個表的情況下 , 你必 須選擇記錄 條數最少的表作 表。如果有 3 個以上的表 查詢 , 那就需要 選擇 交叉表 (intersection table) , 交叉表是指那個被其他表所引用的表 .
2 ????? WHERE 子句中的 序.:
ORACLE 采用自下而上的 序解析 WHERE 子句 , 根據 個原理 , 表之 接必 寫在其他 WHERE 條件之前 , 那些可以 過濾 掉最大數量 記錄 的條件必 寫在 WHERE 子句的末尾 .
3 ????? SELECT 子句中避免使用 ‘ * ‘
ORACLE 在解析的 程中 , 會將 '*' 依次 轉換 成所有的列名 , 個工作是通 過查詢 數據字典完成的 , 意味著將耗 更多的 時間
4 ????? 減少 訪問 數據 的次數:
ORACLE 在內部 行了 多工作 : 解析 SQL , 估算索引的利用率 , , 數據 等;
5 ????? SQL*Plus , SQL*Forms Pro*C 中重新 ARRAYSIZE 參數 , 可以增加 次數據 庫訪問 索數據量 , 議值為 200
6 ????? 使用 DECODE 函數來減少 時間
使用 DECODE 函數可以避免重 復掃 描相同 記錄 或重 復連 接相同的表 .
7 ????? 整合 簡單 , 關聯 的數據 庫訪問
如果你有幾個 簡單 的數據 庫查詢語 , 你可以把它 整合到一個 查詢 ( 即使它 沒有 )
8 ????? 除重 復記錄
最高效的 除重 復記錄 方法 ( 使用了 ROWID) 例子:
DELETE ?FROM ?EMP E ?WHERE ?E.ROWID > (SELECT MIN(X.ROWID)
FROM ?EMP X ?WHERE ?X.EMP_NO = E.EMP_NO);
9 ????? TRUNCATE 替代 DELETE
除表中的 記錄時 , 在通常情況下 , (rollback segments ) 用來存放可以被恢 的信息 . 如果你沒有 COMMIT ,ORACLE 會將數據恢 除之前的狀 ( 準確地 是恢 除命令之前的狀況 ) 而當運用 TRUNCATE , 段不再存 放任何可被恢 的信息 . 當命令運行后 , 數據不能被恢 . 因此很少的 源被 調 , 時間 也會很短 . ( 者按 : TRUNCATE 只在 除全表適用 ,TRUNCATE DDL 不是 DML)
10 ? 盡量多使用 COMMIT
只要有可能 , 在程序中盡量多使用 COMMIT, 這樣 程序的性能得到提高 , 需求也會因 COMMIT 放的 源而減少 :
COMMIT
放的 :
a.
段上用于恢 數據的信息 .
b.
被程序 得的
c. redo log buffer
中的空
d. ORACLE
管理上述 3 種資 源中的內部花
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 ? 減少 表的 查詢
在含有子 查詢 SQL 句中 , 要特 注意減少 表的 查詢 . 例子:
???? SELECT ?TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER? FROM ?TAB_COLUMNS ? WHERE ?VERSION = 604)
13 ? 內部函數提高 SQL 效率 .
復雜 SQL 往往 牲了 行效率 . 掌握上面的運用函數解決 問題 的方法在 實際 工作中是非常有意
14 ? 使用表的 (Alias)
當在 SQL 句中 接多個表 , 使用表的 名并把 名前 Column . 這樣 一來 , 就可以減少解析的 時間 并減少那些由 Column 引起的 錯誤 .
15 ? 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' )
16 ? 識別 ' 低效 ' SQL 句:
然目前各 種關 SQL 化的 形化工具 出不 , 但是寫出自己的 SQL 工具來解決 問題 是一個最好的方法:
SELECT ?EXECUTIONS , DISK_READS, BUFFER_GETS,
ROUND ((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2 ) Hit_radio,
ROUND (DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
FROM ?V$SQLAREA
WHERE ?EXECUTIONS>0
AND ?BUFFER_GETS > 0
AND ?(BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY ? 4 DESC ;
17 ? 用索引提高效率:
索引是表的一個概念部分 , 用來提高 索數據的效率, ORACLE 使用了一個 復雜 的自平衡 B-tree . 通常 , 索引 查詢 數據比全表 描要快 . ORACLE 找出 查詢 Update 句的最佳路徑 , ORACLE 化器將使用索引 . 聯結 多個表 使用索引也可以提高效率 . 另一個使用索引的好 , 它提供了主 (primary key) 的唯一性 驗證 . 。那些 LONG LONG RAW 數據 , 你可以索引幾乎所有的列 . 通常 , 在大型表中使用索引特 有效 . 當然 , 你也會 發現 , 描小表 , 使用索引同 能提高效率 . 然使用索引能得到 查詢 效率的提高 , 但是我 也必 注意到它的代價 . 索引需要空 來存 , 也需要定期 維護 , 當有 記錄 在表中增減或索引列被修改 , 索引本身也會被修改 . 意味著 記錄 INSERT , DELETE , UPDATE 此多付出 4 , 5 次的磁 I/O . 索引需要 外的存 , 那些不必要的索引反而會使 查詢 應時間變 . 定期的重構索引是有必要的 .
ALTER ? INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
18 ? EXISTS DISTINCT
當提交一個包含一 多表信息 ( 比如部 表和雇 ) 查詢時 , 避免在 SELECT 子句中使用 DISTINCT. 一般可以考 EXIST , EXISTS 使 查詢 迅速 , RDBMS 核心模 將在子 查詢 的條件一旦 滿 足后 , 立刻返回 . 例子:
?????? ( 低效 ):
SELECT ? DISTINCT ?DEPT_NO,DEPT_NAME ? FROM ?DEPT D , EMP E
WHERE ?D.DEPT_NO = E.DEPT_NO
( 高效 ):
SELECT ?DEPT_NO,DEPT_NAME ? FROM ?DEPT D ? WHERE ? EXISTS ( SELECT ‘X'
FROM ?EMP E ? WHERE ?E.DEPT_NO = D.DEPT_NO ) ;
19 ? sql 句用大寫的 ;因 oracle 是先解析 sql 句,把小寫的字母 轉換 成大寫的再
20 ? java 中盡量 少用 接符 接字符串
21 ? 避免在索引列上使用 NOT 通常 , 
要避免在索引列上使用 NOT, NOT 生在和在索引列上使用函數相同的影響 . ORACLE” 遇到 ”NOT, 他就會停止使用索引 行全表 .
22 ? 避免在索引列上使用 算.
WHERE 子句中,如果索引列是函數的一部分. 化器將不使用索引而使用全表 描.
:
低效:
SELECT … FROM ?DEPT ?WHERE SAL * 12 > 25000;
高效 :
SELECT … FROM DEPT WHERE SAL > 25000/12;
23 ? >= 替代 >
高效 :
SELECT * FROM ?EMP ?WHERE ?DEPTNO >=4
低效 :
SELECT * FROM EMP WHERE DEPTNO >3
兩者的區 在于 , 前者 DBMS 將直接跳到第一個 DEPT 等于 4 記錄 而后者將首先定位到 DEPTNO=3 記錄 并且向前 描到第一個 DEPT 大于 3 記錄 .
24 ? UNION OR ( 適用于索引列 )
通常情況下 , UNION WHERE 子句中的 OR 將會起到 好的效果 . 索引列使用 OR 將造成全表 . 注意 , 以上 規則 針對 多個索引列有效 . 如果有 column 沒有被索引 , 查詢 效率可能會因 你沒有 選擇 OR 而降低 . 在下面的例子中 , LOC_ID REGION 上都建有索引 .
高效 :
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”
低效 :
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
如果你 持要用 OR, 那就需要返回 記錄 最少的索引列寫在最前面 .
25 ? IN 來替 OR ?
是一條 簡單 規則 ,但是 實際 行效果 還須檢驗 ,在 ORACLE8i 下,兩者的 行路徑似乎是相同的. 
低效 :
SELECT …. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30
高效
SELECT FROM LOCATION WHERE LOC_IN ? IN (10,20,30);
26 ? 避免在索引列上使用 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;
27 ? 是使用索引的第一個列:
如果索引是建立在多個列上 , 只有在它的第一個列 (leading column) where 子句引用 , 化器才會 選擇 使用 索引 . 也是一條 簡單 而重要的 規則 ,當 引用索引的第二個列 , 化器使用了全表 描而忽略了索引
28 ? UNION-ALL UNION ( 如果有可能的 )
SQL 句需要 UNION 兩個 查詢結 果集合 , 兩個 果集合會以 UNION-ALL 的方式被合并 , 然后在 出最 終結 果前 行排序 . 如果用 UNION ALL 替代 UNION, 這樣 排序就不是必要了 . 效率就會因此得到提高 . 需要注意的是 UNION ALL 將重 復輸 出兩個 果集合中相同 記錄 . 因此各位 是要從 業務 需求分析使用 UNION ALL 的可行性 . UNION 對結 果集合排序 , 個操作會使用到 SORT_AREA_SIZE 這塊 內存 . 這塊 內存的 化也是相當重要的 . 下面的 SQL 可以用來 查詢 排序的消耗量
低效:
SELECT ?ACCT_NUM, BALANCE_AMT
FROM ?DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
高效 :
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION ALL
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
29 ? WHERE 替代 ORDER BY
ORDER BY 子句只在兩 種嚴 格的條件下使用索引 .
ORDER BY
中所有的列必 包含在相同的索引中并保持在索引中的排列 .
ORDER BY
中所有的列必 義為 非空 .
WHERE
子句使用的索引和 ORDER BY 子句中所使用的索引不能并列 .
例如 :
DEPT 包含以下列 :
DEPT_CODE PK NOT NULL
DEPT_DESC NOT NULL
DEPT_TYPE NULL
低效 : ( 索引不被使用 )
SELECT DEPT_CODE? FROM ?DEPT ? ORDER BY ?DEPT_TYPE
高效 : ( 使用索引 )
SELECT DEPT_CODE ? FROM ?DEPT ? WHERE ?DEPT_TYPE > 0
30 ? 避免改 索引列的 .:
當比 不同數據 型的數據 , ORACLE 動對 簡單 轉換 .
EMPNO 是一個數 值類 型的索引列 .
SELECT … ? FROM EMP ? WHERE ? EMPNO = ‘123'
實際 , 經過 ORACLE 轉換 , :
SELECT … ? FROM EMP ?WHERE ?EMPNO = TO_NUMBER(‘123')
幸運的是 , 轉換 沒有 生在索引列上 , 索引的用途沒有被改 .
, EMP_TYPE 是一個字符 型的索引列 .
SELECT … ? FROM EMP ? WHERE EMP_TYPE = 123
句被 ORACLE 轉換為 :
SELECT … ? FROM EMP ? WHERETO_NUMBER(EMP_TYPE)=123
內部 生的 轉換 , 個索引將不會被用到 ! 了避免 ORACLE 你的 SQL 式的 轉換 , 最好把 轉換 式表 出來 . 注意當字符和數 較時 , ORACLE 轉換 值類 型到字符
31 ? 需要當心的 WHERE 子句 :
某些 SELECT 句中的 WHERE 子句不使用索引 . 里有一些例子 .
在下面的例子里 , (1) ‘!=' 將不使用索引 . , 索引只能告 你什 存在于表中 , 而不能告 你什 不存在于表中 . (2) ‘||' 字符 接函數 . 就象其他函數那 , 停用了索引 . (3) ‘+' 是數學函數 . 就象其他數學函數那 , 停用了索引 . (4) 相同的索引列不能互相比 , 將會啟用全表 .
32 ? a. 如果 索數據量超 30% 的表中 記錄 . 使用索引將沒有 著的效率提高 .
b.
在特定情況下 , 使用索引也 會比全表 描慢 , 是同一個數量 上的區 . 而通常情況下 , 使用索引比全表 描要 幾倍乃至幾千倍 !
33 ? 避免使用耗 費資 源的操作 :
DISTINCT,UNION,MINUS,INTERSECT,ORDER BY SQL 句會啟 SQL 引擎
行耗 費資 源的排序 (SORT) 功能 . DISTINCT 需要一次排序操作 , 而其他的至少需要 行兩次排序 . 通常 , UNION, MINUS , INTERSECT SQL 句都可以用其他方式重寫 . 如果你的數據 SORT_AREA_SIZE 調 配得好 , 使用 UNION , MINUS, INTERSECT 也是可以考 , 竟它 的可 性很
34 ? GROUP BY:
提高 GROUP BY 句的效率 , 可以通 將不需要的 記錄 GROUP BY 之前 過濾 . 下面兩個 查詢 返回相同 果但第二個明 就快了 .
低效 :
SELECT JOB , AVG(SAL)
FROM EMP
GROUP JOB
HAVING JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
高效 :
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
GROUP JOB
?

oracle SQL性能優化


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产色产综合色产在线观看视频 | 99精品国产高清自在线看超 | 欧美香蕉爽爽人人爽观看猫咪 | 免费看欧美毛片大片免费看 | 99热在这里只有免费精品 | 欧美一级毛片特黄黄 | 一级毛片人与动免费观看 | 91久久免费视频 | 久久不卡| 四虎影视永久免费视频观看 | 亚洲 欧洲 自拍 另类 校园 | 成人伊人 | 日韩久久网 | 香蕉人精品视频多人免费永久视频 | 深夜福利国产福利视频 | 激情时刻| 日韩天天摸天天澡天天爽视频 | 国产原创精品 | 久草视频资源在线 | 欧美一级毛片免费播放aa | 毛片免费观看成人 | www.午夜精品 | 99综合色 | 国产在线小视频 | 九九热在线视频免费观看 | 草草影院国产第一页 | 日韩欧美在线观看视频一区二区 | 韩日一级毛片 | 久久综合丁香 | 日韩亚洲一区中文字幕在线 | 福利院肉动漫视频在线观看 | 国产午夜不卡在线观看视频666 | 一级毛片美国一级j毛片不卡 | 久久精品视频久久 | 欧美成人免费全部观看天天性色 | 成人三级视频在线观看 | 色偷偷青青草原在线视频 | 一级日本特黄毛片视频 | 男人的天堂222eee | 亚洲国产成人精品一区二区三区 | 逆天至尊免费看229集 |