本篇文章給大家分享的是有關(guān)SQL書寫規(guī)范有哪些,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、成都微信小程序、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了天涯免費(fèi)建站歡迎大家使用!一.如何使用高效的索引
1.索引的作用?
舉個例子來說明索引的作用:
一本書西游記一共1250頁,現(xiàn)在你想找到孫悟空大戰(zhàn)黃獅精的章節(jié)拿來看,如果你一頁頁的翻書找可能要翻1000多頁紙才能找到對應(yīng)章節(jié),但是如果你通過目錄來查找就很快速了,在目錄中很容易的找到孫悟空大戰(zhàn)黃獅精在第836頁,直接去書中第836頁就能看到孫悟空大戰(zhàn)黃獅精的章節(jié)所有內(nèi)容了。
數(shù)據(jù)庫中的表就如同一本書,索引如同目錄。書的目錄存放著章節(jié)內(nèi)容標(biāo)題和頁碼的對應(yīng)關(guān)系,而索引存放著數(shù)據(jù)鍵值和表中該行對應(yīng)的位置,知道的數(shù)據(jù)在表中位置就可以快速的訪問到數(shù)據(jù)行,這樣通過索引你就可以快速查出表中想要的數(shù)據(jù)行了。
2.什么樣需求建立索引合理?
前面提到了使用索引可以檢索訪問表中數(shù)據(jù)行,那我們是不是把任何欄位都就建立上索引都好使嘛,當(dāng)然不是。
舉個例子:
公司有3萬員工,數(shù)據(jù)庫中員工基本信息表EMP,主要欄位有工號EMP_NO,姓名EMP_NAME,性別EMP_SEX,部門DEPT,入職時間WORK_DATE等
需求一: 需要通過工號或者姓名查詢員工的詳細(xì)信息
因為工號是唯一的,姓名相同的人也不是很多,對EMP_NO和EMP_NAME分別建立一個單獨(dú)的索引都會對檢索性能提高很多。
需求二: 查詢公司的男員工有多少
因為性別只是二種,建立索引就不合理了,為什么?因為索引中存放的是鍵值和行的物理位置。如果通過索引你需要把索引中所有性別為男的鍵值對應(yīng)的物理位置都找出來(光檢索索引就消耗大量資源),再通過這些位置回表到出對應(yīng)所有行的數(shù)據(jù),效率很低了。
以上主要涉及索引selectivity(選擇性)的概念,索引選擇性計算公式:
索引選擇性 = 基數(shù) / 總行數(shù)
基數(shù):鍵值在table中行數(shù)
總行數(shù):table總行數(shù)
意思公式算出值越小選擇性越強(qiáng),類似EMP_NO,EMP_NAME選擇性就很強(qiáng),EMP_SEX選擇性就很弱。
這里結(jié)合本人經(jīng)驗及多位專家指出設(shè)計和選擇索引欄位時,建議選擇的欄位索引選擇性的值小于1/100 以上,而極端情況下可以到1/10
3.什么樣情形用不到索引?
很多時候有人說明明建立了引為何SQL還是很慢,可以通過執(zhí)行計劃看到索引沒有被使用。為什么沒使用?可能的原因以下:
一.索引欄位使用函數(shù)
如索引欄位serial_number使用了函數(shù)upper使用不到索引
正確方法:如果迫不得已需要在索引欄位中使用函數(shù),可以建立函數(shù)索引替代普通索引
二.不匹配數(shù)據(jù)類型做比較
如WROK_ID欄位是VARCHAR2類型,但是SQL寫為WROK_ID=20190507,字符類型和一個數(shù)字去=比較,DB的查詢優(yōu)化器會在解析時做一個to_number(WROK_ID)=20190507的隱式轉(zhuǎn)換,這樣也用不到索引
正確方法:
直接使用WROK_ID='20190507'字符做比較
三.模糊查詢like ‘%xxx%’ 或‘%xxx’
因為索引Btree數(shù)據(jù)結(jié)構(gòu)決定,在檢索值最前面加% like查詢是無法索引索引的
且只能在檢索值最后面加% like查詢,可使用索引
正確方法:
避免like‘%xxx%’寫法,如有特殊需求查詢like ‘%xxx’可參考反向索引文章:
http://blog.itpub.net/25583515/viewspace-2146401/
四.組合索引沒有使用先導(dǎo)列
CREATE INDEX SFISM4.GWL_INDEX ON SFISM4.R_STATION_REC_T
(GROUP_NAME, WORK_DATE, LINE_NAME)
組合索引(GROUP_NAME, WORK_DATE, LINE_NAME)
因為索引Btree數(shù)據(jù)結(jié)構(gòu)決定,如果在查詢時沒有指定先導(dǎo)列(leading column)第一列GROUP_NAME,只寫WORK_DATE, LINE_NAME時用不到高性能索引的RANGE SCAN,只能使用FULL TAB SCAN或者效能并不高的INDEX SKIP SCAN
正確方法:
寫全先導(dǎo)列查詢或設(shè)計新的索引
五.不等于查詢
<> != 的不等查詢無法使用索引
正確方法:
重新評估業(yè)務(wù)邏輯,以其它變通方法解決
六.NULL,空值
Oracle 無法和NULL 及'',NOT NULL 做比較時使用索引
(注,像MySQL innodb的默認(rèn)定義null欄位 IS NULL是可以使用索引,SQL server非聚族索引的NULL也是可以被索引的)
正確方法:
Oracle中避免和空比較
七.不合理的where條件
比如SN_DETAIL表保留著三年內(nèi)的數(shù)據(jù),現(xiàn)在你要查詢2017年1月到2019年1月的數(shù)據(jù),因為DB的優(yōu)化器會認(rèn)為數(shù)據(jù)量過大,使用索引還不如全表掃描效率
正確方法:
重新評估需求,必要時找DBA協(xié)助
二.SQL,PL/SQL編寫規(guī)范習(xí)慣
1>開發(fā)首先寫好begin..exception..end; 以免遺漏
2>代碼做好縮進(jìn),方便查看
3>代碼和table欄位做好注解,方便后續(xù)他人閱讀
4>table和sp等對象定義好命名前綴后綴規(guī)則,C_ R_ I_ SP_ _T _I等
5>table和sp等對象定義好命名長度,盡可能簡短
6>多次使用值如1/24*60可賦予變量重用,否則每次使用會被運(yùn)算一次帶來開銷
7>避免事務(wù)執(zhí)行過程中失敗業(yè)務(wù)數(shù)據(jù)不一致 exception中可以寫上rollback
8>業(yè)務(wù)邏輯優(yōu)化,避免死鎖,如SP1中第1條更新tab1,第2條更新tab2,SP2中就按照第1條更新tab1,第2條更新tab2。避免在其它SP中出現(xiàn)第1條更新tab2,第2條更新tab1的順序
9>SQL中能不使用distinct,group by,order by,having等操作就不要使用,避免帶來負(fù)載
10>能使用union all操作就不要使用union,union去重操作也會來帶負(fù)載
11>SQL能寫短,就不要太長,避免太多表的join,優(yōu)化器可能會選擇錯誤的執(zhí)行計劃
12>執(zhí)行完事務(wù)記得及時commit,rollback
13>同一個程式處理過程中盡可能減少commit頻率
14>SQLServer查詢時盡量使用nolock,避免lock爭用
15>CS架構(gòu),Clinet機(jī)器名盡可能15位長度之類,方便異常時捕獲分析,Oracle11G及之前版本截取主機(jī)名長度有限,過長會不利于捕獲Clinet機(jī)器分析異常
16>在執(zhí)行過久SQL時,查看執(zhí)行計劃并調(diào)整,也可找資深開發(fā)人員或DBA協(xié)助分析原因
以上就是SQL書寫規(guī)范有哪些,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道。