SQL性能優(yōu)化

SQL性能優(yōu)化

SQL性能優(yōu)化

一柳击、SQL的執(zhí)行順序

順序:FROM——ON——JOIN——WHERE——GROUP BY——SUM旦签、COUNT——HAVING——SELECT——DISTINCT——ORDER BY——LIMIT

與寫SQL的順序不同负芋,SQL的執(zhí)行順序并不是從select開始散庶,而是從from開始

1不傅、FROM:先去獲取from里面的表茴厉,拿到對應(yīng)的數(shù)據(jù)泽台,生成虛擬表1。

2矾缓、ON:對虛擬表1應(yīng)用ON篩選怀酷,符合條件的數(shù)據(jù)生成虛擬表2。

3嗜闻、JOIN:根據(jù)JOIN的類型去執(zhí)行相對應(yīng)的操作胰坟,獲取對應(yīng)的數(shù)據(jù),生成虛擬表3泞辐。

4笔横、WHERE:對虛擬表3的數(shù)據(jù)進(jìn)行條件過濾,符合記錄的數(shù)據(jù)生成虛擬表4咐吼。

5吹缔、GROUP BY:根據(jù)group by中的列,對虛擬表4進(jìn)行數(shù)據(jù)分組操作锯茄,生成虛擬表5厢塘。

6、CUBE|ROLLUP(聚合函數(shù)使用):主要是使用相關(guān)的聚合函數(shù)肌幽,生成虛擬表6晚碾。

7、HAVING:對虛擬表6的數(shù)據(jù)過濾喂急,生成虛擬表7格嘁,這個(gè)過濾是在where中無法完成的,同時(shí)count(expr)返回不為NULL的行數(shù)廊移,而count(1)和count(*)是會返回包括NULL在內(nèi)的行數(shù)糕簿。

8、SELECT:選擇指定的列狡孔,生成虛擬表8懂诗。

9、DISTINCT:數(shù)據(jù)去重苗膝,生成虛擬表9殃恒。

10、ORDER BY:對虛擬表9中的數(shù)據(jù)進(jìn)行指定列的排序,生成虛擬表10离唐。

11隆嗅、LIMIT:取出指定行的記錄,生成虛擬表11侯繁,返回給查詢用戶胖喳。

以上是SQL各關(guān)鍵詞的執(zhí)行順序,如果在一條SQL語句里面你沒有用到某個(gè)關(guān)鍵詞那就不會被執(zhí)行了贮竟。理解SQL的邏輯執(zhí)行順序?qū)ξ覀冊趯?shí)際寫SQL的過程中也會有幫助的丽焊。

二、執(zhí)行計(jì)劃——EXPLAIN

執(zhí)行計(jì)劃咕别,是SQL在數(shù)據(jù)庫中執(zhí)行時(shí)的表現(xiàn)情況,通常用于SQL性能分析,優(yōu)化等場景技健。在MySQL使用 explain 關(guān)鍵字來查看SQL的執(zhí)行計(jì)劃。

基本的語法:EXPLAIN(select * from table)

在常規(guī)SQL語句前面加上EXPLAIN即可

運(yùn)行結(jié)果:

image

參數(shù)解釋:

1惰拱、id:數(shù)字越大越先執(zhí)行雌贱,一樣大則從上往下執(zhí)行,如果為NULL則表示是結(jié)果集偿短,不需要用來查詢欣孤。

2、select_type:

simple:不需要union的操作或者是不包含子查詢的簡單select語句昔逗。

primary:需要union操作或者含有子查詢的select語句降传。

union:連接兩個(gè)select查詢,第一個(gè)查詢是dervied派生表勾怒,第二個(gè)及后面的表select_type都是union婆排。

dependent union:與union一樣,出現(xiàn)在union 或union all語句中笔链,但是這個(gè)查詢要受到外部查詢的影響段只。

union result:包含union的結(jié)果集。

subquery:除了from字句中包含的子查詢外鉴扫,其他地方出現(xiàn)的子查詢都可能是subquery赞枕。

dependent subquery:與dependent union類似,表示這個(gè)subquery的查詢要受到外部表查詢的影響幔妨。

derived:from字句中出現(xiàn)的子查詢鹦赎,也叫做派生表谍椅,其他數(shù)據(jù)庫中可能叫做內(nèi)聯(lián)視圖或嵌套select误堡。

3、table

表名雏吭,如果是用了別名锁施,則顯示別名

4、type

依次從好到差:system,const悉抵,eq_ref肩狂,ref,fulltext姥饰,ref_or_null傻谁,unique_subquery,index_subquery列粪,range审磁,index_merge,index岂座,ALL态蒂,除了all之外,其他的type都可以使用到索引费什,除了index_merge之外钾恢,其他的type只可以用到一個(gè)索引。

system:表中只有一行數(shù)據(jù)或者是空表鸳址。

const:使用唯一索引或者主鍵瘩蚪,返回記錄一定是1行記錄的等值where條件時(shí),通常type是const稿黍。

eq_ref:出現(xiàn)在要連接過個(gè)表的查詢計(jì)劃中募舟,驅(qū)動表只返回一行數(shù)據(jù),且這行數(shù)據(jù)是第二個(gè)表的主鍵或者唯一索引闻察,且必須為not null拱礁,唯一索引和主鍵是多列時(shí),只有所有的列都用作比較時(shí)才會出現(xiàn)eq_ref辕漂。

ref:不像eq_ref那樣要求連接順序呢灶,也沒有主鍵和唯一索引的要求,只要使用相等條件檢索時(shí)就可能出現(xiàn)钉嘹,常見與輔助索引的等值查找鸯乃。

fulltext:全文索引檢索,要注意跋涣,全文索引的優(yōu)先級很高缨睡,若全文索引和普通索引同時(shí)存在時(shí),mysql不管代價(jià)陈辱,優(yōu)先選擇使用全文索引奖年。

ref_or_null:與ref方法類似,只是增加了null值的比較沛贪。實(shí)際用的不多陋守。

unique_subquery:用于where中的in形式子查詢震贵,子查詢返回不重復(fù)值唯一值。

index_subquery:用于in形式子查詢使用到了輔助索引或者in常數(shù)列表水评,子查詢可能返回重復(fù)值猩系,可以使用索引將子查詢?nèi)ブ亍?/p>

range:索引范圍掃描,常見于使用>,<,is null,between ,in ,like等運(yùn)算符的查詢中中燥。

index_merge:表示查詢使用了兩個(gè)以上的索引寇甸,最后取交集或者并集,常見and 疗涉,or的條件使用了不同的索引幽纷。

index:索引全表掃描,把索引從頭到尾掃一遍博敬,常見于使用索引列就可以處理不需要讀取數(shù)據(jù)文件的查詢友浸、可以使用索引排序或者分組的查詢。

all:這個(gè)就是全表掃描數(shù)據(jù)文件偏窝,然后再在server層進(jìn)行過濾返回符合要求的記錄收恢。

5、possible_keys:查詢可能使用到的索引祭往。

6伦意、key:查詢真正使用到的索引。

7硼补、key_len:用于處理查詢的索引長度驮肉。

8、ref:常數(shù)等值查詢顯示const已骇,連接查詢則顯示表的關(guān)聯(lián)字段离钝。

9、rows:執(zhí)行計(jì)劃中估算的掃描行數(shù)褪储,不是精確值卵渴。

10、filtered:表示存儲引擎返回的數(shù)據(jù)在server層過濾后鲤竹,剩下多少滿足查詢的記錄數(shù)量的比例浪读。

11、extra:該字段信息較多辛藻,這里就不一一敘述了碘橘。

在實(shí)際的使用過程中我們需要重點(diǎn)去關(guān)注type、key吱肌、key_len痘拆、rows、extra這幾個(gè)參數(shù)岩榆,type要努力優(yōu)化到range級別错负,all要盡量少的出現(xiàn)坟瓢,在查詢的過程中要盡量使用索引勇边,提高效率犹撒,在extra里面出現(xiàn)Using filesort, Using temporary是不太好的,要去優(yōu)化提高性能粒褒。

三识颊、優(yōu)化TIPS

1、盡量少用select *

因?yàn)闀黾硬槐匾南霓确兀瑂elect 后面直接加上需要的字段名祥款。

2、IN 包含的值不應(yīng)過多

IN本身這個(gè)操作消耗就比較高月杉,如果IN里面是連續(xù)的數(shù)值刃跛,則可以用between代替,IN里面的字段如果是添加了索引苛萎,效率還是可以的桨昙,目前測試一萬以內(nèi)還是可以,但是超過了結(jié)果可能會有點(diǎn)爆炸腌歉,不要問我為什么

3蛙酪、in和exists、not in 和 not exists

exists以外層表為驅(qū)動表翘盖,先被訪問桂塞,適合于外表小而內(nèi)表大的情況。

in則是先執(zhí)行子查詢馍驯,適合外表大而內(nèi)表小的情況阁危,

一般情況是不推薦使用not in,因?yàn)樾史浅5停?/p>

eg:

1)select * from table_a where table_a.id not in (select table_b.id from table_b)

2)select * from table_a left join table_b on table_a.id = table_b.id where table_b.id is null

語句2的效率是要高于語句1的汰瘫,SQL的結(jié)果是獲取到在table_a中存在但是table_b中不存在的數(shù)據(jù)欲芹,如果直接用not in是不走索引的,而且在table_b比較大的時(shí)候效率會非常低吟吝,實(shí)際工作中我試了一下直接not in菱父,然后數(shù)據(jù)達(dá)到一萬條的時(shí)候大概需要150S左右才能查出數(shù)據(jù)(感謝DBA和運(yùn)維不殺之恩),我采取的方法是剑逃,先查出兩個(gè)表的交集浙宜,這樣得到的表會小很多,而且是用的in蛹磺,效率會高很多粟瞬,然后再用not in,最終的效果也是一樣萤捆,但是時(shí)間只要2.56S裙品,然后采取語句2的關(guān)聯(lián)表來處理俗批,時(shí)間縮短到了1.42S,基本上效率是比較高的市怎,當(dāng)然理想的是在1S內(nèi)岁忘。

4、盡量少用or区匠,同時(shí)盡量用union all 代替union

or兩邊的字段如果有不走索引的會導(dǎo)致整個(gè)的查詢不走索引干像,從而導(dǎo)致效率低下,這時(shí)可以使用union all或者union驰弄,而兩者的區(qū)別是union是將兩個(gè)結(jié)果合并之后再進(jìn)行唯一性的過濾操作麻汰,效率會比union all低很多,但是union all需要兩個(gè)數(shù)據(jù)集沒有重復(fù)的數(shù)據(jù)戚篙。

5五鲫、分段和分頁查詢

在掃描行數(shù)較多的情況下可以采取分段查詢,循環(huán)遍歷岔擂,結(jié)果合并處理位喂,

使用合理的分頁方式,在數(shù)據(jù)表量級逐漸增加的時(shí)候智亮,limit分頁查詢的效率會降低忆某。

1)select id,col from table limit 888888,1000

2)select id,col from table where id > 888887 limit 1000

取前一頁的最大行數(shù)的id,然后根據(jù)這個(gè)id來限制下一頁的起點(diǎn)阔蛉。

6弃舒、不建議使用%前綴模糊查詢

like "%abc"和like "%abc%"會導(dǎo)致索引失效而進(jìn)行全文搜索。

如果你還有什么比較好的優(yōu)化tips歡迎分享状原!

</article>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末聋呢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子颠区,更是在濱河造成了極大的恐慌削锰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毕莱,死亡現(xiàn)場離奇詭異器贩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)朋截,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門蛹稍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人部服,你說我怎么就攤上這事唆姐。” “怎么了廓八?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵奉芦,是天一觀的道長赵抢。 經(jīng)常有香客問我,道長声功,這世上最難降的妖魔是什么烦却? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮减噪,結(jié)果婚禮上短绸,老公的妹妹穿的比我還像新娘车吹。我一直安慰自己筹裕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布窄驹。 她就那樣靜靜地躺著朝卒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乐埠。 梳的紋絲不亂的頭發(fā)上抗斤,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音丈咐,去河邊找鬼瑞眼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛棵逊,可吹牛的內(nèi)容都是我干的伤疙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼辆影,長吁一口氣:“原來是場噩夢啊……” “哼徒像!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蛙讥,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤锯蛀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后次慢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旁涤,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年迫像,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了劈愚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侵蒙,死狀恐怖造虎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纷闺,我是刑警寧澤算凿,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布份蝴,位于F島的核電站,受9級特大地震影響氓轰,放射性物質(zhì)發(fā)生泄漏婚夫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一署鸡、第九天 我趴在偏房一處隱蔽的房頂上張望案糙。 院中可真熱鬧,春花似錦靴庆、人聲如沸时捌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奢讨。三九已至,卻和暖如春焰薄,著一層夾襖步出監(jiān)牢的瞬間拿诸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工塞茅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亩码,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓野瘦,卻偏偏與公主長得像描沟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子缅刽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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