自己遇到的一些SQL優(yōu)化

字符的分隔

(思想,先構(gòu)造在拼接)

SELECTa.id,b.NAME,A.WORK_TYPE,b."ID"

?

FROMCRD.T_CRD_SCORE_CONFIGa

?

leftJOINEMERP.T_BASE_WORK_TYPE_ALLbon','||A.WORK_TYPE||','like'%,'||b.id||',%'GROUPBYA.ID

分組函數(shù):GROUP BY

? 分組函數(shù),可以多次分組

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

子查詢

?? 這次寫代碼的時候,有一些字段上線前著急要和實際的業(yè)務(wù)邏輯,使用了子查詢,有的可以使用連接查詢,但是沒有優(yōu)化

記錄的標(biāo)記字段

這次編寫代碼的時候,標(biāo)記這條記錄是否刪除,使用,顯示,在編寫SQL的時候出現(xiàn)了一些漏寫的字段,以后再寫的時候,一定要注意全

表空間(用戶)

在編寫SQL的時候,沒有注意在表前標(biāo)記空間名(用戶)。

OR的使用

OR一定要合理運用,總忘記這個

ORDER BY 的使用

1. 只有ORDER BY 子句中可以使用select列表中列的別名

2. 使用了ORDER BY子句的查詢不能用作表表達式(視圖、內(nèi)聯(lián)表值函數(shù)、子查詢、派生表和共用表達式)

3. 在分頁的時候,如果是多表連接的,要是條件排序的條件的值一致,在分頁的時候可能兩次的結(jié)果有重復(fù)數(shù)據(jù)。

exts和in用法

1. exists對外表做循環(huán),每次循環(huán)對內(nèi)表查詢;in將內(nèi)表和外表做hash連接

2. 使用exists oracle會先檢查主查詢,使用in,首先執(zhí)行子查詢,將結(jié)果存儲在臨時表中

3. 如果兩個表大小相當(dāng),in和exists差別不大

4. 如果兩個表大小相差較大則子查詢表大的用exists,子查詢表小的用in

5.盡量不要使用not in

union和union all

? 1. 使用場景:需要將兩個select語句結(jié)果整體顯示時,可以使用union和unionall

2.union對兩個結(jié)果集取并集不包含重復(fù)結(jié)果同時進行默認(rèn)規(guī)則的排序;而union all對兩個結(jié)果集去并集,包括? 重復(fù)行,不進行排序

? 3.union需要進行重復(fù)值掃描,效率低,如果沒有要刪除重復(fù)行,應(yīng)該使用union all

? 4.insersect和minus分別交集和差集,都不包括重復(fù)行,并且進行默認(rèn)規(guī)則的排序

 5.可以將多個結(jié)果集合并

? 6.必須保證select集合的結(jié)果有相同個數(shù)的列,并且每個列的類型是一樣的(列名不一定要相同,會默認(rèn)將第一個結(jié)果的列名作為結(jié)果集的列名)

指定where的條件順序

1. 默認(rèn)情況下,Oracle采用自下而上的順序解析where字句,因此在處理多表查詢的時候,表之間的連接必須寫在其他的where條件之前,但是過濾數(shù)據(jù)記錄的條件則必須寫在where子句的尾部,以便在過濾了數(shù)據(jù)之后再進行連接處理,這樣可以提升sql語句的性能

LEFT--JOIN? 注釋事項

在使用left-join的時候一定要注意順序問題。

SQL語句盡量用大寫的

因為oracle總是先解析SQL語句,把小寫的字母轉(zhuǎn)換成大寫的再執(zhí)行。

使用表的別名

? ? 當(dāng)在SQL語句中連接多個表時, 盡量使用表的別名并把別名前綴于每個列上。這樣一來,就可以減少解析的時間并 減少那些由列歧義引起的語法錯誤。

選擇最有效率的表名順序(只在基于規(guī)則的優(yōu)化器(RBO)中有效)

? ORACLE 的解析器按照從右到左的順序處理FROM子句中的表名,F(xiàn)ROM子句中寫在最后的表(基礎(chǔ)表也稱為驅(qū)動表,driving table)將被最先處理,在FROM子句中包含多個表的情況下,必須選擇記錄條數(shù)最少的表作為基礎(chǔ)表。如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎(chǔ)表, 交叉表是指那個被其他表所引用的表。

避免使用耗費資源的操作

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

?

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

?

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

?

?如果數(shù)據(jù)庫的SORT_AREA_SIZE調(diào)配得好,使用UNION,MINUS,INTERSECT也是可以考慮。?

?

用Where子句替換HAVING子句

? ? 避免使用HAVING子句,HAVING只會在檢索出所有記錄之后才對結(jié)果集進行過濾。這個處理需要排序,總計等操作。最好能通過WHERE子句限制記錄的數(shù)目。(非oracle中)on、where、having這三個都可以加條件的子句中,on是最先執(zhí)行,where次之,having最后。

避免在索引列上使用計算

? WHERE子句中,如果索引列是函數(shù)的一部分,優(yōu)化器將不使用索引而使用全表掃描。

BETWEEN? ? AND

取值是兩邊都要。

NVL2(expr1,expr2,expr3)

NVL2(表達式,不為空設(shè)值,為空設(shè)值)

to_char用法

(1)用作日期轉(zhuǎn)換

? ? to_char(date,'格式');

? ? select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from dual;

(2)處理數(shù)字

? ? to_char(number,'格式');

? ?? select to_char(88877) from dual;

? ?? select to_char(1234567890,'099999999999999')? from dual;

? ?? select to_char(12345678,'999,999,999,999')? from dual;

? ?? select to_char(123456,'99.999')? from dual;

? ?? select to_char(1234567890,'999,999,999,999.9999')? from dual;

(3) 處理錢

? ? to_char(salary,'$99,99');

? select TO_CHAR(123,'$99,999.9') from dual;

(4)用于進制轉(zhuǎn)換:將10進制轉(zhuǎn)換為16進制;

? ? select to_char(4567,'xxxx') from dual;

? ? select to_char(123,'xxx') from dual;

to_date

select sysdate,to_date('20170615','yyyymmdd')from dual;

select sysdate,to_date('20170615','yyyy-mm-dd')from dual;

select sysdate,to_date('20170615','yyyy/mm/dd')from dual;

select sysdate,to_date('20170615','yyyy-mm-dd hh24:mi:ss')from dual;

應(yīng)盡量避免在 where 子句中使用 or 來連接條件

select id from t where num=10 or Name = 'admin'

?

可以這樣查詢:

?

select id from t where num = 10

union all

select id from t where Name = 'admin'

模糊查詢

當(dāng)模糊匹配以%開頭時,該列索引將失效,若不以%開頭,該列索引有效。

常用函數(shù)

FLOOR(x) ? 返回小于x的最大整數(shù)值

AVG(col)返回指定列的平均值

COUNT(col)返回指定列中非NULL值的個數(shù)

MIN(col)返回指定列的最小值

MAX(col)返回指定列的最大值

SUM(col)返回指定列的所有值之和

LEFT(str,x)返回字符串str中最左邊的x個字符

TRIM(str)去除字符串首部和尾部的所有空格

UCASE(str)或UPPER(str) 返回將字符串str中所有字符轉(zhuǎn)變?yōu)榇髮懞蟮慕Y(jié)果

優(yōu)化總結(jié)口訣

? 全值匹配我最愛,最左前綴要遵守;

? 帶頭大哥不能死,中間兄弟不能斷;

?? ? ? ? 索引列上少計算,范圍之后全失效;

? LIKE百分寫最右,覆蓋索引不寫星;

? 不等空值還有or,? 索引失效要少用;

?? ? ? ? VAR引號不可丟,SQL高級也不難;

如何分析SQL

1.觀察,至少跑一天,看看生產(chǎn)的慢SQL情況。

2.開啟慢查詢?nèi)罩荆O(shè)置閥值,比如超過5秒鐘就是慢SQL,并將它抓取出來

3.explain+慢SQL分析

4.show profile

5.DBA進行SQL數(shù)據(jù)庫服務(wù)器的參數(shù)調(diào)優(yōu)

總結(jié):

1.慢查詢的開啟并捕獲

2.explain+慢SQL分析

3.show profile查詢SQL在MySql里面的執(zhí)行細(xì)節(jié)和生命周期情況

4.SQl數(shù)據(jù)服務(wù)器的參數(shù)調(diào)優(yōu)

?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第一天 7月13日OCP筆記: Oracle Ocp11g準(zhǔn)備資料: OracleFundmentals 書 管理...
    fjxCode閱讀 2,879評論 0 4
  • 轉(zhuǎn) # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    呂品?閱讀 10,108評論 0 44
  • 1.簡介 數(shù)據(jù)存儲有哪些方式?電子表格,紙質(zhì)文件,數(shù)據(jù)庫。 那么究竟什么是關(guān)系型數(shù)據(jù)庫? 目前對數(shù)據(jù)庫的分類主要是...
    喬震閱讀 2,004評論 0 2
  • 第一節(jié)課上的數(shù)學(xué)老師講的十以內(nèi)的加法,老師還讓我們做的數(shù)學(xué)課本46頁的題。第二節(jié)課我們上語文老師給我們講的課文小小...
    王昭捷閱讀 143評論 0 0
  • 那時的我們 守住了彼此 守住了回憶 卻守不住那黃昏下的影子 任其模糊 任其消散 而隨之煙滅的 是你我心中的那一抹殘...
    希爾G3閱讀 129評論 0 0

友情鏈接更多精彩內(nèi)容