oracle 帶有變量的語句_【成都校區】Oracle SQL語句之常見優化方法總結

本帖出自于黑馬程序員成都中心,更多資源可關注微信公眾號

694e170813096cf542f87047c9af433d.png

1、SQL語句盡量用大寫的;

因為oracle總是先解析SQL語句,把小寫的字母轉換成大寫的再執行。

2、使用表的別名:

當在SQL語句中連接多個表時, 盡量使用表的別名并把別名前綴于每個列上。這樣一來,

就可以減少解析的時間并減少那些由列歧義引起的語法錯誤。

3、選擇最有效率的表名順序(只在基于規則的優化器(RBO)中有效):

ORACLE 的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最后的表

(基礎表也稱為驅動表,driving table)將被最先處理,在FROM子句中包含多個表的情況下,

必須選擇記錄條數最少的表作為基礎表。如果有3個以上的表連接查詢, 那就需要選擇交叉

表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表。

4、WHERE子句中的連接順序:

ORACLE采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他

WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。

5、SELECT子句中避免使用 * :

ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名, 這個工作是通過查詢數據字

典完成的, 這意味著將耗費更多的時間。

6、減少訪問數據庫的次數:

ORACLE在內部執行了許多工作: 解析SQL語句,估算索引的利用率,綁定變量,讀數據塊等。

7、整合簡單、無關聯的數據庫訪問:

如果有幾個簡單的數據庫查詢語句,可以整合到一個查詢中(即使它們之間沒有關系)。

8、在SQL*Plus,SQL*Forms和Pro*C中重新設置ARRAYSIZE參數,可以增加每次數據庫訪問

的檢索數據量,建議值為200。

9、刪除重復記錄:

最高效的刪除重復記錄方法 :

DELETE FROM TEMP E

WHERE E.ROWID > (SELECT MIN(X.ROWID)

FROM TEMP1 X WHERE X.TEMP_NO = E.TEMP_NO);

10、減少對表的查詢:

在含有子查詢的SQL語句中,要特別注意減少對表的查詢。

SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT

TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604);

11、避免使用耗費資源的操作:

帶有DISTINCT、UNION、MINUS、INTERSECT、ORDER BY的SQL語句會啟動SQL引擎執行

耗費資源的排序(SORT)功能。DISTINCT需要一次排序操作,而其他的至少需要執行兩次排序。

通常,帶有UNION、MINUS、INTERSECT的SQL語句都可以用其他方式重寫。

如果數據庫的SORT_AREA_SIZE調配得好,使用UNION,MINUS,INTERSECT也是可以考慮。

12、優化GROUP BY:

提高GROUP BY 語句的效率,可以通過將不需要的記錄在GROUP BY之前過濾掉。

下面兩個查詢返回相同結果但明顯第二個效率更高。

低效:

SELECT JOB,AVG(AGE) FROM TEMP

GROUP BY JOB HAVING JOB = 'STUDENT' OR JOB = 'MANAGER';

高效:

SELECT JOB,AVG(AGE) FROM EMP

WHERE JOB = 'STUDENT' OR JOB = 'MANAGER' GROUP BY JOB;

13、根據需要用UNION ALL替換UNION:

當SQL語句需要UNION兩個查詢結果集合時,這兩個結果集合會以UNION-ALL的方式被合并,

然后在輸出最終結果前進行排序。如果用UNION ALL替代UNION, 這樣排序就不是必要了。

效率就會因此得到提高。需要注意UNION ALL將重復輸出兩個結果集合中相同記錄。因此要

從業務需求使用UNION ALL的可行性。UNION 將對結果集合排序,這個操作會使用到

SORT_AREA_SIZE這塊內存。對于這塊內存的優化也很重要。

低效:

SELECT USER_ID,BILL_ID FROM USER_TAB1 WHERE AGE = '20'

UNION

SELECT USER_ID,BILL_ID FROM USER_TAB2 WHERE AGE = '20';

高效:

SELECT USER_ID,BILL_ID FROM USER_TAB1 WHERE AGE = '20'

UNION ALL

SELECT USER_ID,BILL_ID FROM USER_TAB2 WHERE AGE = '20';

14、用EXISTS替換DISTINCT:

當SQL包含一對多表查詢時,避免在SELECT子句中使用DISTINCT,一般用EXIST替換,EXISTS

查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結果。

(低效):

SELECT DISTINCT USER_ID,BILL_ID FROM USER_TAB1 D,USER_TAB2 E

WHERE D.USER_ID= E.USER_ID;

(高效):

SELECT USER_ID,BILL_ID FROM USER_TAB1 D WHERE EXISTS(SELECT 1

FROM USER_TAB2 E WHERE E.USER_ID= D.USER_ID);

15、盡量多使用COMMIT:

只要有可能,在程序中盡量多使用COMMIT,這樣程序的性能得到提高,需求也會因為COMMIT

所釋放的資源而減少。

COMMIT所釋放的資源:

a. 回滾段上用于恢復數據的信息。

b. 被程序語句獲得的鎖。

c. redo log buffer 中的空間。

d. ORACLE為管理上述3種資源中的內部花銷。

16、用Where子句替換HAVING子句:

避免使用HAVING子句,HAVING只會在檢索出所有記錄之后才對結果集進行過濾。這個處理需

要排序,總計等操作。最好能通過WHERE子句限制記錄的數目。

(非oracle中)on、where、having這三個都可以加條件的子句中,on是最先執行,where次之,

having最后。

a、on是先把不符合條件的記錄過濾后才進行統計,可以減少中間運算要處理的數據,速度是

最快的;

b、where比having快點,因為它過濾數據后才進行sum,在兩個表聯接時才用on的,所以在一

個表的時候,就剩下where跟having比較了。在單表查詢統計的情況下,如果要過濾的條件沒

有涉及到要計算字段,那它們的結果是一樣的,只是where可以使用rushmore技術,而having

就不能,在速度上后者要慢。

如果要涉及到計算的字段,就表示在沒計算之前,這個字段的值是不確定的,where的作用

時間是在計算之前就完成的,而having就是在計算后才起作用的,所以在這種情況下,兩者

的結果會不同。在多表聯接查詢時,on比where更早起作用。系統首先根據各個表之間的關聯

條件,把多個表合成一個臨時表后,再由where進行過濾,然后再計算,計算完后再由having

進行過濾。

17、用TRUNCATE替代DELETE:

當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments)用來存放可以被恢復的

信息。如果你沒有COMMIT事務,ORACLE會將數據恢復到刪除之前的狀態(準確地說是恢復到執

行刪除命令之前的狀況)。而當運用TRUNCATE時,回滾段不再存放任何可被恢復的信息。當命

令運行后,數據不能被恢復。因此很少的資源被調用,執行時間也會很短。

注:TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML。

18、使用DECODE函數來減少處理時間:

使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表。

19、用EXISTS替代IN、用NOT EXISTS替代 NOT IN:

在基于基礎表的查詢中經常需要對另一個表進行聯接。在這種情況下, 使用EXISTS(或NOT

EXISTS)通常將提高查詢的效率。在子查詢中,NOT IN子句將執行一個內部的排序和合并。無

論在哪種情況下,NOT IN都是最低效的(要對子查詢中的表執行了一個全表遍歷)。所以盡量將

NOT IN改寫成外連接(Outer Joins)或NOT EXISTS。

(高效)

SELECT A.* FROM TEMP(基礎表) A WHERE AGE > 0

AND EXISTS(SELECT 1 FROM TEMP1 WHERE A.ID= ID AND NAME='TOM');

(低效)

SELECT A.* FROM TEMP(基礎表) A WHERE AGE > 0

AND A.ID IN(SELECT ID FROM TEMP1 WHERE NAME ='TOM');

20、用索引提高效率:

索引是表的一個概念部分,用來提高檢索數據的效率,ORACLE使用了復雜的自平衡B-tree結

構。通常通過索引查詢數據比全表掃描要快。當ORACLE找出執行查詢和Update語句的最佳路徑

時, ORACLE優化器將使用索引。同樣在聯結多個表時使用索引也可以提高效率。

另一個使用索引的好處是,它提供了主鍵(primary key)的唯一性驗證。那些LONG或LONG RAW

數據類型, 你可以索引幾乎所有的列。通常在大型表中使用索引特別有效。在掃描小表時,使

用索引同樣能提高效率。

使用索引雖能得到查詢效率的提高,但也必須注意到它的代價。索引需要空間來存儲,也需

要定期維護, 每當有記錄在表中增減或索引列被修改時, 索引本身也會被修改。這意味著每

條記錄的INSERT、DELETE、UPDATE將為此多付出4、5 次的磁盤I/O。因為索引需要額外的存

儲空間和處理,一些不必要的索引反而會使查詢反應時間變慢。

定期的重構索引:

ALTER INDEX REBUILD

21、用>=替代>:

高效:

SELECT * FROM TEMP WHERE ID >=4;

低效:

SELECT * FROM TEMP WHERE ID >3;

區別:前者DBMS將直接跳到第一個ID等于4的記錄而后者將首先定位到ID=3的記錄并且向前掃

描到第一個ID大于3的記錄。

22、避免在索引列上使用NOT: 

NOT會產生在和在索引列上使用函數相同的影響。當ORACLE遇到NOT,就會停止使用索引轉

而執行全表掃描。

23、避免在索引列上使用計算:

WHERE子句中,如果索引列是函數的一部分,優化器將不使用索引而使用全表掃描。

低效:

SELECT … FROM TEMP WHERE SAL * 12 > 25000;

高效:

SELECT … FROM TEMP WHERE SAL > 25000/12;

24、用UNION替換OR(適用于索引列):

用UNION替換WHERE子句中的OR將會起到較好的效果。對索引列使用OR將造成全表掃

描。注意,以上規則只針對多個索引列有效。如果有column沒有被索引, 查詢效率可能

會因為你沒有選擇OR而降低。

高效:

SELECT * FROM USER_TAB1 WHERE USER_ID = 10

UNION

SELECT * FROM USER_TAB1 WHERE AGE = 20;

低效:

SELECT * FROM USER_TAB1 WHERE USER_ID = 10 OR AGE = 20;

25、避免在索引列上使用IS NULL和IS NOT NULL

避免在索引中使用任何可以為空的列,ORACLE將無法使用該索引。

對于單列索引,如果列包含空值,索引中將不存在此記錄。

對于復合索引,如果每個列都為空,索引中同樣不存在此記錄。如果至少有一個列不為

空,則記錄存在于索引中。

如果唯一性索引建立在表的A列和B列上, 并且表中存在一條記錄的A,B值為(123,null),

ORACLE將不接受下一條具有相同A,B值(123,null)的記錄(插入)。然而如果所有的索引列

都為空,ORACLE將認為整個鍵值為空而空不等于空。因此你可以插入10000條具有相同鍵值

的記錄,當然它們都是空! 因為空值不存在于索引列中,所以WHERE子句中對索引列進行空

值比較將使ORACLE停用該索引。

低效: (索引失效)

SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;

高效: (索引有效)

SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;

26、總是使用索引的第一個列:

如果索引是建立在多個列上,只有在它的第一個列(leading column)被where子句引用時,

優化器才會選擇使用該索引。

當引用索引的第二個列時,優化器使用了全表掃描而忽略了索引。

27、用WHERE替代ORDER BY:

ORDER BY 子句只在以下兩種嚴格的條件下使用索引:

(1)ORDER BY中所有的列必須包含在相同的索引中并保持在索引中的排列順序。

(2)ORDER BY中所有的列必須定義為非空。

WHERE子句使用的索引和ORDER BY子句中所使用的索引不能并列。例如:

USER_ID PK NOT NULL

USER_DESC NOT NULL

USER_TYPE NULL

低效: (索引不被使用)

SELECT USER_ID FROM USER_TAB ORDER BY USER_TYPE;

高效: (使用索引)

SELECT USER_ID FROM USER_TAB WHERE USER_TYPE> 0;

28、避免改變索引列的類型:

當比較不同數據類型的數據時, ORACLE自動對列進行簡單的類型轉換。

假設 USER_ID 是一個數值類型的索引列。

SELECT … FROM USER_TAB WHERE USER_ID = '123';

實際上,經過ORACLE類型轉換, 語句轉化為:

SELECT … FROM USER_TAB WHERE USER_ID = TO_NUMBER('123');

幸運的是,類型轉換沒有發生在索引列上,索引的用途沒有被改變。

現在,假設USER_TYPE是一個字符類型的索引列。

SELECT … FROM USER_TAB WHERE USER_TYPE = 123 ;

這個語句被ORACLE轉換為:

SELECT … FROM USER_TAB WHERE TO_NUMBER(USER_TYPE)=123;

因為內部發生的類型轉換, 這個索引將不會被用到! 為了避免ORACLE對你的SQL進行隱式的類

型轉換, 最好把類型轉換用顯式表現出來。

注:當字符和數值比較時, ORACLE會優先轉換數值類型到字符類型。

SELECT … FROM USER_TAB WHERE TO_NUMBER(USER_TYPE)=123;

29、WHERE子句:

某些SELECT 語句中的WHERE子句不使用索引。

(1)'!='不走索引。索引只能告訴我們什么存在于表中, 而不能告訴你什么不在表中。

(2)'||'是字符連接函數。就象其他函數那樣, 停用了索引。

(3)'+'是數學函數。和其他數學函數一樣, 停用了索引。

(4)相同的索引列不能互相比較,這將會啟用全表掃描。

30、 a.如果檢索數據量超過30%的表中記錄數,使用索引將沒有顯著的效率提高。

b.在特定情況下,使用索引也許會比全表掃描更慢,但這是同一個數量級上的區別。

而通常情況下,使用索引比全表掃描要塊幾倍乃至幾千倍。

31、查'低效執行'的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;

0c35382785e24f271158fc826a3f75e2.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276049.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276049.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276049.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

js 獲取上下文后面的路徑_通過在數據后面顯示上下文來可視化公眾意見

js 獲取上下文后面的路徑In 1824, The Harrisburg Pennsylvanian, a newspaper from a town in Pennsylvania conducted the first known public opinion polls in history, and successfully predicted the result of the vote in the close race between Andrew Jackson and …

甘肅甘南步班郵遞員:草原上的“遞愛”艱途

圖為甘肅甘南藏族自治州碌曲縣郎木寺鎮郵政支局的投遞員進行投遞工作。&#xff08;資料圖&#xff09; 鐘欣 攝 中新網蘭州1月25日電 (吳玉蒿)漸近春節&#xff0c;劉權英投遞郵件的工作愈加繁重。現年45歲的劉權英是甘肅甘南藏族自治州碌曲縣郎木寺鎮郵政支局的一名投遞員。由…

核心編程6——線程

Note 0:了進程實際是由兩個組件組成的:一個進程內核對象和一個地址空間.類似地,線程也由兩個組件組成:一個是線程的內核對象,操作系統用它管理線程.內核對象還是系統用來存放線程統計信息的地方.一個線程堆棧,用于維護線程執行時所需的所有函數參數和局部變量.Note 1:進程是有惰…

PHP解決搶購、秒殺、搶樓、抽獎等阻塞式高并發庫存防控超量的思路方法

轉載鏈接&#xff1a;http://www.4u4v.net/thinking-approach-to-buy-spike-grab-floor-sweepstakes-and-other-high-concurrent-blocking-prevention-excess-inventory-solve-php.html 如今在電商行業里,秒殺搶購活動已經是商家常用促銷手段。但是庫存數量有限&#xff0c;而同…

看了就會的 Node.js 三大基礎模塊常用 API

大家好&#xff0c;我是若川。歡迎加我微信 ruochuan12&#xff0c;加群交流學習。今天分享一篇nodejs基礎的文章。點擊下方卡片關注我&#xff0c;或者查看源碼等系列文章。在日常使用 Node 進行開發的時候&#xff0c;會使用到一些文件系統、路徑操作等基礎 API&#xff0c;這…

vue-cli3插件初體驗

vue-cli3發布自2018年8月&#xff0c;距離現在還不是特別久&#xff0c;最好搭建項目剛好用到&#xff0c;所以寫下這篇文章&#xff0c;記錄一下踩坑經歷。vue的作者說過&#xff0c;vue-cli的本質是模版的拉取&#xff0c;太多的配置導致了模版的難以維護&#xff0c;所以重構…

ios設計登錄功能_親愛的產品設計師,這是iOS 14的新功能

ios設計登錄功能On June 22, 2020 Apple previewed iOS 14 for the first time. As always there are quite some changes you should know about as a product designer like widgets, pickers, app clips, permissions and more.2020年6月22日&#xff0c;Apple首次預覽iOS 1…

c++ int 轉 short_C/C++結構體內存對齊

在面試或工作中&#xff0c;經常會遇到內存對齊的問題。這里結合我的理解談一談對內存對齊的理解。1. 為什么要內存對齊&#xff0c;不對齊會怎么樣&#xff1f;內存中存放數據是為了給CPU使用&#xff0c;CPU訪問內存數據時會受到地址總線寬度的限制&#xff0c;也就是一次能從…

對于日訪問量達到1W IP的處理方法

轉自&#xff1a;http://www.java123.net/56026-2.html 對于日訪問量達到1W IP的處理方法 一、1萬ip真是不高&#xff1a; 1.常用數據用緩存&#xff0c;減輕數據庫壓力。 2.詳細頁數據生成靜態頁面。 二、10000算是相當小的了,不需要什么特殊的處理機制,只要符合最一般的…

數據契約(DataContract)

WCF第一要素就是契約: 服務契約用于聲明可用于遠程訪問的類型。在Interface或class開始處使用服務契約標簽. [ServiceContract] Public interface Iservice { } 接口調用契約的好處: 1. 同一服務類型可以實現多個不相干的服務契約. 2. 有利于版本升級 3. 按照…

jakob slam_Jakob Nielsen針對用戶界面設計的第二種可用性啟發法

jakob slamIn the pursuit of providing great user experiences, it’s imperative that digital products are evaluated. A 為了提供出色的用戶體驗&#xff0c;必須對數字產品進行評估。 一個 heuristic evaluation is essential to delivering great user experiences. I…

微軟Office 365正式上架Mac App Store

今天&#xff0c;Office 365正式在Mac App Store上架&#xff0c;Mac用戶可以輕松下載Word&#xff0c;Outlook&#xff0c;Excel&#xff0c;PowerPoint&#xff0c;OneNote以及整套微軟的熱門應用程序。用戶還可以從應用程序內訂購Office 365。蘋果全球開發者關系高級主管Sha…

一文搞懂瀏覽器原理

大家好&#xff0c;我是若川。最近這幾年&#xff0c;云計算的普及和 HTML5 技術的快速發展&#xff0c;越來越多的應用轉向了瀏覽器 / 服務器&#xff08;B/S&#xff09;架構&#xff0c;這種改變讓瀏覽器的重要性與日俱增&#xff0c;視頻、音頻、游戲幾大核心場景也都在逐漸…

python處理excel可視化_python如何將excel數據處理可視化

python將excel數據處理可視化的方法&#xff1a;首先安裝xlrd與xlwt庫&#xff0c;進行表格讀取&#xff1b;然后使用pyecharts生成Echarts圖表的類庫&#xff1b;最后安裝Echarts讀取Excel數據及顯示即可。python將excel數據處理可視化的方法&#xff1a;Excel表操作python操作…

dataframe中將一列數據切分成多列

為什么80%的碼農都做不了架構師&#xff1f;>>> 原sheet中數據 目的 將【備注】列切分成【key】列和【value】列 Python sheet[key] sheet[備注].str.extract(r(_.*(?\u503c))) sheet[value] sheet[備注].str.extract(r((?<).*))結果 參考 pandas.Series.st…

matplotlib可視化_EDA:Geopandas,Matplotlib和Bokeh中的可視化

matplotlib可視化Nowadays, everyone is immersed with plenty of data from news sources, cellphones, laptops, workplaces, and so on. Data conveys with tons of information from different data variables like date, string, numeric, and geographical format. How t…

(轉)結婚那天,媽問我:坐在角落里象兩個要飯模樣的人是誰?

人人看到的文章 很感人~~~~結婚那天&#xff0c;媽問我&#xff1a;坐在角落里象兩個要飯模樣的人是誰&#xff1f; 我看過去的時候&#xff0c;有個老頭正盯著我&#xff0c;旁邊還有個老太太&#xff0c;發現我看著他們時趕忙低下頭。我不認識他們但也不象要飯的&#xff0c;…

nginx-1.13.x源碼安裝

Nginx 安裝配置【依賴庫】[ zlib ]&#xff08;下載&#xff09;http://download.chinaunix.net/download.php?id24013&ResourceID12241 [ pcre ]apt-get install libpcre-dev[ openssl ]&#xff08;下載&#xff09;http://download.chinaunix.net/download.php?id3937…

小技巧!CSS 整塊文本溢出省略特性探究

大家好&#xff0c;我是若川。歡迎加我微信 ruochuan12&#xff0c;長期交流學習。今天的文章很有意思&#xff0c;講一講整塊文本溢出省略打點的一些有意思的細節。點擊下方卡片關注我&#xff0c;或者查看源碼系列文章。文本超長打點我們都知道&#xff0c;到今天&#xff08…

linux配置ip地址 suse_SUSE Linux下設置IP的兩種方法

第一種SUSE Linux IP設置方法ifconfig eth0 192.168.1.22 netmask 255.255.255.0 uproute add default gw 192.168.1.2釋義&#xff1a;#IP配置&#xff0c;包括子網掩碼,看情況修改eth0和192.168.1.22#網關修改 ,看情況修改192.168.1.2第二種SUSE Linux IP設置方法在suse操作系…