SQL語(yǔ)句優(yōu)化, since 2022-04-22

(2022.04.22 Fri)
SQL語(yǔ)句的優(yōu)化目的在于提高SQL語(yǔ)句的運(yùn)行效率给梅。注意SQL優(yōu)化和數(shù)據(jù)庫(kù)優(yōu)化的區(qū)別。

SQL語(yǔ)句的優(yōu)化有很大一部分是和SQL索引有關(guān),善用索引避免全表掃描可以提升運(yùn)行效率。

利用索引

  1. 避免全表掃描,在WHERE和ORDER BY涉及的列上建立索引

以下列出的各種查詢(xún)方法都會(huì)避開(kāi)索引而直接使用全表掃描啰脚,建議使用修改建議做查詢(xún)。

  1. 使用IN/NOT IN的地方实夹,可用=代替橄浓,或EXIST,或>=, <=亮航,或BETWEEN代替荸实,
# 低效
SELECT name_field, score_field 
FROM table_a 
WHERE score_field IN (90, 91, 92);
############################
SELECT name_field, score_field FROM table_a 
WHERE score_field >= 90 AND score_field <=92;
############################
SELECT name_field, score_field FROM table_a 
WHERE score_field = 90
UNION ALL
SELECT name_field, score_field FROM table_a 
WHERE score_field = 91
UNION ALL
...
############################
SELECT name_field, score_field FROM table_a 
WHERE score_field BETWEEN 90 AND 92;
  1. NULL值作為查詢(xún)條件。建議在創(chuàng)建表示設(shè)置默認(rèn)值非NULL缴淋,比如0
SELECT * FROM table_a
WHERE some_field IS NULL;
###########################
SELECT * FROM table_a
WHERE some_field = 0;
  1. 使用OR作為條件從句准给,建議使用UNION ALL代替泄朴。
SELECT * FROM table_a
WHERE sid = 10 OR sid = 20;
##########################
SELECT * FROM table_a
WHERE sid = 10
UNION ALL
SELECT * FROM table_a
WHERE sid = 20;
  1. '%abc%'的首字母是%的檢索方式,在大數(shù)據(jù)量的情況建議換成'abc%'露氮,或者在MySQL中用INSTR(field, substr)指令檢索祖灰。如果是小數(shù)據(jù)量的數(shù)據(jù),可使用'%abc%'指令查詢(xún)
SELECT * FROM table_a 
WHERE content LIKE '%abc%'
##########################
SELECT * FROM table_a 
WHERE content LIKE 'abc%'
##########################
SELECT * FROM table_a 
WHERE INSTR(content, 'abc');
  1. WHERE語(yǔ)句中對(duì)字段進(jìn)行表達(dá)式或函數(shù)操作畔规,轉(zhuǎn)換為其他局扶;或WHERE子句中=左側(cè)的運(yùn)算應(yīng)放在右側(cè)
SELECT * FROM table_a
WHERE some_field/10 > 10;
#########################
SELECT * FROM table_a
WHERE some_field > 100;
SELECT * FROM table_a
WHERE SUBSTRING(some_field, 1, 3) = 'abc';
#########################
SELECT * FROM table_a
WHERE some_field LIKE 'abc%';
  1. WHERE從句中使用的!=, <>,建議用其他方式和語(yǔ)法代替

SQL優(yōu)化

  1. SELECT語(yǔ)句中用SELECT <col_names>代替SELECT *叁扫,避免找出不需要的字段三妈,占用過(guò)多CPU資源。另莫绣,查全部變量不會(huì)使用覆蓋索引(?)從而降低了查詢(xún)效率

  2. JOIN查詢(xún)代替子查詢(xún)沈跨。子查詢(xún)往往涉及IN操作,而IN操作不僅會(huì)使用全表掃描兔综,還會(huì)生成臨時(shí)表,等查詢(xún)結(jié)束再銷(xiāo)毀臨時(shí)表狞玛,給系統(tǒng)造成負(fù)擔(dān)软驰。用JOIN操作代替

SELECT a.name, a.id, b.subjects, b.score
FROM stu_info a
INNER JOIN stu_score b
ON a.id = b.id;
  1. 能用UNION的語(yǔ)句盡量換成UNION ALL語(yǔ)句。這兩個(gè)指令都可進(jìn)行結(jié)果的合并與整理心肪,但UNION在執(zhí)行過(guò)程中會(huì)對(duì)重復(fù)的選項(xiàng)做篩選锭亏,之后進(jìn)行排序,在返回結(jié)果前會(huì)將重復(fù)的選項(xiàng)重新加入到返回結(jié)果中硬鞍。UNION ALL對(duì)重復(fù)的數(shù)據(jù)不做操作慧瘤,不對(duì)數(shù)據(jù)做排序處理。顯然后者的效率更高固该。

  2. 使用表的別名代替表名锅减,減少解析時(shí)間和友列歧義導(dǎo)致的語(yǔ)法錯(cuò)誤

  3. 調(diào)整WHERE子句中的篩選字段連接順序。MySQL中是自左向右伐坏、自上而下的順序?qū)ψ兞孔龊Y選怔匣,應(yīng)將過(guò)濾數(shù)據(jù)多的條件往前放,最快縮小數(shù)據(jù)集

  4. 小表驅(qū)動(dòng)大表 - 多表關(guān)聯(lián)查詢(xún)(JOIN)時(shí)桦沉,在MySQL中執(zhí)行WHERE語(yǔ)句中的表從左到右查詢(xún)(Oracle相反)每瞒,第一張表會(huì)涉及全表掃描,所以把小表放在前面纯露, 大表放在后面剿骨,提高效率。能用INNER JOIN盡量不用LEFT JOIN

  5. 考慮語(yǔ)句的執(zhí)行順序埠褪,在先執(zhí)行的WHERE子句中先篩選數(shù)據(jù)浓利,為后面的操作提供更小的數(shù)據(jù)挤庇,用于取代HAVING子句做數(shù)據(jù)篩選

  6. 創(chuàng)建數(shù)據(jù)表時(shí),字段的類(lèi)型varcharchar好荞膘,因前者更靈活罚随,后者占用空間固定且檢索效率低

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市羽资,隨后出現(xiàn)的幾起案子淘菩,更是在濱河造成了極大的恐慌,老刑警劉巖屠升,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件潮改,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡腹暖,警方通過(guò)查閱死者的電腦和手機(jī)舌界,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)芙扎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事袜炕。” “怎么了言疗?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵诀艰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我黄绩,道長(zhǎng)羡洁,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任爽丹,我火速辦了婚禮筑煮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘粤蝎。我一直安慰自己真仲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布初澎。 她就那樣靜靜地躺著袒餐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谤狡。 梳的紋絲不亂的頭發(fā)上灸眼,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音墓懂,去河邊找鬼焰宣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛捕仔,可吹牛的內(nèi)容都是我干的匕积。 我是一名探鬼主播盈罐,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼闪唆!你這毒婦竟也來(lái)了盅粪?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤悄蕾,失蹤者是張志新(化名)和其女友劉穎票顾,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體帆调,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奠骄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了番刊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片含鳞。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖芹务,靈堂內(nèi)的尸體忽然破棺而出蝉绷,到底是詐尸還是另有隱情,我是刑警寧澤枣抱,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布熔吗,位于F島的核電站,受9級(jí)特大地震影響沃但,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜佛吓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一宵晚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧维雇,春花似錦淤刃、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至津滞,卻和暖如春铝侵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背触徐。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工咪鲜, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人撞鹉。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓疟丙,卻偏偏與公主長(zhǎng)得像颖侄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子享郊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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