30 條 SQL 語句性能優(yōu)化策略,建議收藏带污!

關(guān)于MySQL的知識點總結(jié)了一個思維導(dǎo)圖僵控,希望對大家所有幫助!

image

關(guān)注公眾號:程序員白楠楠鱼冀,領(lǐng)取2020最新Java面試題手冊(200多頁PDF文檔)报破。

1

對查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描千绪,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引充易。

2

應(yīng)盡量避免在 where 子句中對字段進(jìn)行 null 值判斷,創(chuàng)建表時NULL是默認(rèn)值荸型,但大多數(shù)時候應(yīng)該使用NOT NULL盹靴,或者使用一個特殊的值,如0瑞妇,-1作為默 認(rèn)值稿静。

3

應(yīng)盡量避免在 where 子句中使用!=或<>操作符, MySQL只有對以下操作符才使用索引:<辕狰,<=改备,=,>蔓倍,>=悬钳,BETWEEN盐捷,IN,以及某些時候的LIKE默勾。

4

應(yīng)盡量避免在 where 子句中使用 or 來連接條件碉渡, 否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描, 可以 使用UNION合并查詢:select id from t where num=10 union all select id from t where num=20

5

in 和 not in 也要慎用灾测,否則會導(dǎo)致全表掃描爆价,對于連續(xù)的數(shù)值,能用 between 就不要用 in 了:Select id from t where num between 1 and 3

6

下面的查詢也將導(dǎo)致全表掃描:select id from t where name like ‘%abc%’ 或者select id from t where name like ‘%abc’若要提高效率媳搪,可以考慮全文檢索铭段。而select id from t where name like ‘a(chǎn)bc%’ 才用到索引

7

如果在 where 子句中使用參數(shù),也會導(dǎo)致全表掃描秦爆。

8

應(yīng)盡量避免在 where 子句中對字段進(jìn)行表達(dá)式操作序愚,應(yīng)盡量避免在where子句中對字段進(jìn)行函數(shù)操作

9

很多時候用 exists 代替 in 是一個好的選擇:select num from a where num in(select num from b).用下面的語句替換:select num from a where exists(select 1 from b where num=a.num)

10

索引固然可以提高相應(yīng)的 select 的效率,但同時也降低了 insert 及 update 的效率等限,因為 insert 或 update 時有可能會重建索引爸吮,所以怎樣建索引需要慎重考慮,視具體情況而定望门。一個表的索引數(shù)最好不要超過6個形娇,若太多則應(yīng)考慮一些不常使用到的列上建的索引是否有必要。

11

應(yīng)盡可能的避免更新 clustered 索引數(shù)據(jù)列筹误, 因為 clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲順序桐早,一旦該列值改變將導(dǎo)致整個表記錄的順序的調(diào)整,會耗費相當(dāng)大的資源厨剪。若應(yīng)用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列哄酝,那么需要考慮是否應(yīng)將該索引建為 clustered 索引。

12

盡量使用數(shù)字型字段祷膳,若只含數(shù)值信息的字段盡量不要設(shè)計為字符型陶衅,這會降低查詢和連接的性能,并會增加存儲開銷直晨。

13

盡可能的使用 varchar/nvarchar 代替 char/nchar 搀军, 因為首先變長字段存儲空間小,可以節(jié)省存儲空間勇皇,其次對于查詢來說奕巍,在一個相對較小的字段內(nèi)搜索效率顯然要高些。

14

最好不要使用”“返回所有:select from t 儒士,用具體的字段列表代替“*”,不要返回用不到的任何字段檩坚。

15

盡量避免向客戶端返回大數(shù)據(jù)量着撩,若數(shù)據(jù)量過大诅福,應(yīng)該考慮相應(yīng)需求是否合理。

16

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

17

使用“臨時表”暫存中間結(jié)果

簡化SQL語句的重要方法就是采用臨時表暫存中間結(jié)果氓润,但是,臨時表的好處遠(yuǎn)遠(yuǎn)不止這些薯鳍,將臨時結(jié)果暫存在臨時表咖气,后面的查詢就在tempdb中了,這可以避免程序中多次掃描主表挖滤,也大大減少了程序執(zhí)行中“共享鎖”阻塞“更新鎖”崩溪,減少了阻塞,提高了并發(fā)性能斩松。

18

一些SQL查詢語句應(yīng)加上nolock伶唯,讀、寫是會相互阻塞的惧盹,為了提高并發(fā)性能乳幸,對于一些查詢,可以加上nolock钧椰,這樣讀的時候可以允許寫粹断,但缺點是可能讀到未提交的臟數(shù)據(jù)。使用 nolock有3條原則嫡霞。查詢的結(jié)果用于“插瓶埋、刪、改”的不能加nolock 秒际!查詢的表屬于頻繁發(fā)生頁分裂的悬赏,慎用nolock !使用臨時表一樣可以保存“數(shù)據(jù)前影”娄徊,起到類似Oracle的undo表空間的功能闽颇,能采用臨時表提高并發(fā)性能的,不要用nolock 寄锐。

19

常見的簡化規(guī)則如下:不要有超過5個以上的表連接(JOIN)兵多,考慮使用臨時表或表變量存放中間結(jié)果。少用子查詢橄仆,視圖嵌套不要過深,一般視圖嵌套不要超過2個為宜剩膘。

20

將需要查詢的結(jié)果預(yù)先計算好放在表中,查詢的時候再Select盆顾。這在SQL7.0以前是最重要的手段怠褐。例如醫(yī)院的住院費計算。

21

用OR的字句可以分解成多個查詢您宪,并且通過UNION 連接多個查詢奈懒。他們的速度只同是否使用索引有關(guān),如果查詢需要用到聯(lián)合索引奠涌,用UNION all執(zhí)行的效率更高.多個OR的字句沒有用到索引,改寫成UNION的形式再試圖與索引匹配磷杏。一個關(guān)鍵的問題是否用到索引溜畅。

22

在IN后面值的列表中,將出現(xiàn)最頻繁的值放在最前面极祸,出現(xiàn)得最少的放在最后面慈格,減少判斷的次數(shù)。

23

盡量將數(shù)據(jù)的處理工作放在服務(wù)器上遥金,減少網(wǎng)絡(luò)的開銷浴捆,如使用存儲過程。存儲過程是編譯好汰规、優(yōu)化過汤功、并且被組織到一個執(zhí)行規(guī)劃里、且存儲在數(shù)據(jù)庫中的SQL語句溜哮,是控制流語言的集合滔金,速度當(dāng)然快。反復(fù)執(zhí)行的動態(tài)SQL,可以使用臨時存儲過程茂嗓,該過程(臨時表)被放在Tempdb中餐茵。

24

當(dāng)服務(wù)器的內(nèi)存夠多時,配制線程數(shù)量 = 最大連接數(shù)+5述吸,這樣能發(fā)揮最大的效率忿族;否則使用 配制線程數(shù)量<最大連接數(shù)啟用SQL SERVER的線程池來解決,如果還是數(shù)量 = 最大連接數(shù)+5,嚴(yán)重的損害服務(wù)器的性能蝌矛。

25

查詢的關(guān)聯(lián)同寫的順序

select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = ‘JCNPRH39681’ (A = B ,B = ‘號碼’)

select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = ‘JCNPRH39681’ and b.referenceid = ‘JCNPRH39681’ (A = B ,B = ‘號碼’道批, A = ‘號碼’)

select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = ‘JCNPRH39681’ and a.personMemberID = ‘JCNPRH39681’ (B = ‘號碼’, A = ‘號碼’)

26

盡量使用exists代替select count(1)來判斷是否存在記錄入撒,count函數(shù)只有在統(tǒng)計表中所有行數(shù)時使用隆豹,而且count(1)比count(*)更有效率。

27

盡量使用“>=”茅逮,不要使用“>”璃赡。

28

索引的使用規(guī)范:索引的創(chuàng)建要與應(yīng)用結(jié)合考慮,建議大的OLTP表不要超過6個索引献雅;盡可能的使用索引字段作為查詢條件碉考,尤其是聚簇索引,必要時可以通過index index_name來強制指定索引挺身;避免對大表查詢時進(jìn)行table scan侯谁,必要時考慮新建索引;在使用索引字段作為條件時,如果該索引是聯(lián)合索引良蒸,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引技扼,否則該索引將不會被使用;要注意索引的維護(hù)嫩痰,周期性重建索引,重新編譯存儲過程窍箍。

29

下列SQL條件語句中的列都建有恰當(dāng)?shù)乃饕模珗?zhí)行速度卻非常慢:

SELECT * FROM record WHERE substrINg(card_no,1,4)=’5378’ (13秒)

SELECT * FROM record WHERE amount/30< 1000 (11秒)

SELECT * FROM record WHERE convert(char(10),date,112)=’19991201’ (10秒)

分析:

WHERE子句中對列的任何操作結(jié)果都是在SQL運行時逐列計算得到的,因此它不得不進(jìn)行表搜索椰棘,而沒有使用該列上面的索引纺棺;如果這些結(jié)果在查詢編譯時就能得到,那么就可以被SQL優(yōu)化器優(yōu)化邪狞,使用索引祷蝌,避免表搜索,因此將SQL重寫成下面這樣:

SELECT * FROM record WHERE card_no like ‘5378%’ (< 1秒)

SELECT * FROM record WHERE amount< 1000*30 (< 1秒)

SELECT * FROM record WHERE date= ‘1999/12/01’ (< 1秒)

30

當(dāng)有一批處理的插入或更新時帆卓,用批量插入或批量更新巨朦,絕不會一條條記錄的去更新!

總結(jié)

關(guān)注公眾號:程序員白楠楠, 領(lǐng)取2020最新Java面試題手冊(200多頁PDF文檔)剑令。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末糊啡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吁津,更是在濱河造成了極大的恐慌棚蓄,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碍脏,死亡現(xiàn)場離奇詭異梭依,居然都是意外死亡,警方通過查閱死者的電腦和手機典尾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門役拴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人急黎,你說我怎么就攤上這事扎狱。” “怎么了勃教?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵淤击,是天一觀的道長。 經(jīng)常有香客問我故源,道長污抬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮印机,結(jié)果婚禮上矢腻,老公的妹妹穿的比我還像新娘。我一直安慰自己射赛,他們只是感情好多柑,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著楣责,像睡著了一般竣灌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秆麸,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天初嘹,我揣著相機與錄音,去河邊找鬼沮趣。 笑死屯烦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的房铭。 我是一名探鬼主播驻龟,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼育叁!你這毒婦竟也來了迅脐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤豪嗽,失蹤者是張志新(化名)和其女友劉穎谴蔑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體龟梦,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡隐锭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了计贰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钦睡。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖躁倒,靈堂內(nèi)的尸體忽然破棺而出荞怒,到底是詐尸還是另有隱情,我是刑警寧澤秧秉,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布褐桌,位于F島的核電站,受9級特大地震影響象迎,放射性物質(zhì)發(fā)生泄漏荧嵌。R本人自食惡果不足惜呛踊,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望啦撮。 院中可真熱鬧谭网,春花似錦、人聲如沸赃春。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽聘鳞。三九已至薄辅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抠璃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工脱惰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搏嗡,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓拉一,卻偏偏與公主長得像采盒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蔚润,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1磅氨、對查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描嫡纠,首先應(yīng)考慮在where及order by涉及的列上建立索引烦租。 2、應(yīng)盡量避...
    奇點一氪閱讀 316評論 0 5
  • 1除盏、對查詢進(jìn)行優(yōu)化叉橱,應(yīng)盡量避免全表掃描,首先應(yīng)考慮在where及order by涉及的列上建立索引者蠕。 2窃祝、應(yīng)盡量避...
    小帥明3號閱讀 108評論 0 0
  • SQL語句性能優(yōu)化 1, 對查詢進(jìn)行優(yōu)化踱侣,應(yīng)盡量避免全表掃描粪小,首先應(yīng)考慮在 where 及 order by 涉及...
    林海之閱讀 161評論 0 0
  • 對查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描抡句,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引探膊。 應(yīng)盡量避...
    guanguans閱讀 448評論 0 3
  • 漸變的面目拼圖要我怎么拼? 我是疲乏了還是投降了猾担? 不是不允許自己墜落袭灯, 我沒有滴水不進(jìn)的保護(hù)膜。 就是害怕變得面...
    悶熱當(dāng)乘涼閱讀 4,249評論 0 13