字符的分隔
(思想,先構(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)
?