后端程序員必看,13個(gè)寫(xiě)SQL的好建議
SQL是一種數(shù)據(jù)庫(kù)的結(jié)構(gòu)化查詢語(yǔ)言,常用的關(guān)系型數(shù)據(jù)庫(kù)有MySQL,SQL Server,Oracle,Access等。其實(shí)就是對(duì)存儲(chǔ)在數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行查詢等操作的一種語(yǔ)言,如果你有語(yǔ)言學(xué)習(xí)的基礎(chǔ),那么學(xué)起SQL一定簡(jiǎn)單多了。每一個(gè)意見(jiàn)和建議都是一筆好財(cái)富,建議收藏~
1. 在執(zhí)行刪除或者更新語(yǔ)句,盡量加上limit,它是SQL后悔藥加了limit 主要有這些好處:
- 降低寫(xiě)錯(cuò)SQL的代價(jià), 如果不加limit,執(zhí)行的時(shí)候一不小心手抖或卡機(jī),數(shù)據(jù)大概就全被刪掉了,刪錯(cuò)了怎么辦?加了limit 200,一切就不同了,可以通過(guò)binlog日志快速恢復(fù)。SQL效率可能會(huì)更高,你在SQL行中,加了limit 1,如果第一條就命中目標(biāo)return, 沒(méi)有l(wèi)imit的話,還會(huì)繼續(xù)執(zhí)行掃描表。
- 避免了長(zhǎng)事務(wù),delete執(zhí)行時(shí),如果age加了索引,MySQL會(huì)將所有相關(guān)的行加寫(xiě)鎖和間隙鎖,所有執(zhí)行相關(guān)行會(huì)被鎖住,如果刪除數(shù)量大,直接無(wú)法使用相關(guān)業(yè)務(wù)。當(dāng)你刪除數(shù)據(jù)量很大時(shí),加 limit限制記錄數(shù),就不容易把cpu打滿。
2. 變更SQL操作先在測(cè)試環(huán)境測(cè)試,可以避免有語(yǔ)法錯(cuò)誤就放到生產(chǎn)上。變更SQL操作需要寫(xiě)明詳細(xì)操作步驟,特別是有依賴關(guān)系的時(shí)候,比如:先修改表結(jié)構(gòu)再增加對(duì)應(yīng)的數(shù)據(jù)。
更換Sql操作有回滾方案,并在上生產(chǎn)前,review對(duì)應(yīng)變更SQL。
3. where后面的字段,留意其數(shù)據(jù)類(lèi)型的隱式轉(zhuǎn)換,這樣可以優(yōu)化性能。因?yàn)闆](méi)加單引號(hào)時(shí),是字符串和數(shù)字的比較,類(lèi)型不匹配,MySQL就會(huì)做隱式的類(lèi)型轉(zhuǎn)換,把它們轉(zhuǎn)換為浮點(diǎn)數(shù)再做比較,最后導(dǎo)致索引失效。
4. 在操作生產(chǎn)的數(shù)據(jù)時(shí),修改或者刪除SQL,先寫(xiě)WHERE查一下,確認(rèn)后再補(bǔ)充 delete 或 update。
5. 減少不必要的字段返回,可以節(jié)省資源、減少網(wǎng)絡(luò)開(kāi)銷(xiāo),用到覆蓋索引,減少回表,提高查詢效率。比如運(yùn)用select <具體字段> 代替 select * 。
6. 數(shù)據(jù)庫(kù)和表的字符集盡量統(tǒng)一使用UTF8編碼,可以避免亂碼問(wèn)題以及不同字符集比較轉(zhuǎn)換,導(dǎo)致的索引失效問(wèn)題。若想存儲(chǔ)表情,選擇utf8mb4來(lái)進(jìn)行存儲(chǔ),請(qǐng)注意它與utf-8的區(qū)別。
7. 盡量使用varchar代替 char。因?yàn)槭紫茸冮L(zhǎng)字段存儲(chǔ)空間小,可以節(jié)省存儲(chǔ)空間。
8. 慎用distinct關(guān)鍵字,它一般用來(lái)過(guò)濾重復(fù)記錄,以返回不重復(fù)的記錄??梢栽诓樵円粋€(gè)字段或者很少字段的情況下使用時(shí),能帶來(lái)優(yōu)化效果。但如果在字段很多的時(shí)候使用,會(huì)降低查詢效率。
9. SQL命令行修改數(shù)據(jù),養(yǎng)成begin + commit 事務(wù)的習(xí)慣,這也是一顆SQL后悔藥。
10. 索引命名要規(guī)范,主鍵索引名為 pk_ 字段名;唯一索引名為 uk _字段名 ;普通索引名則為 idx _字段名。比如pk_即primary key;uk_即unique key;idx_即index 的簡(jiǎn)稱(chēng)。
11. where從句中不對(duì)列進(jìn)行函數(shù)轉(zhuǎn)換和表達(dá)式計(jì)算,因?yàn)樗饕猩鲜褂胢ysql的內(nèi)置函數(shù),索引失效。
12. SQL語(yǔ)句中不IN包含的值不能太多,如果數(shù)值過(guò)多,產(chǎn)生的消耗也就較大。MySQL對(duì)于IN做了相應(yīng)的優(yōu)化,即將IN中的常量全部存儲(chǔ)在一個(gè)數(shù)組里面,而且這個(gè)數(shù)組是排好序的。能用between就不要用in了,或者使用連接來(lái)替換。
13. 在適當(dāng)?shù)臅r(shí)候,使用覆蓋索引。它能夠讓你的SQL語(yǔ)句不需要回表,僅訪問(wèn)索引就能得到全部需要的數(shù)據(jù),大大提升了查詢效率。
























