一文帶你了解Sql優(yōu)化

我們后臺開發(fā)人員每天都難免與數(shù)據(jù)庫打交道,那么你在寫sql語句的時候有注重到自己sql的效率嗎伶选?當你sql查詢速度很慢的時候你有想過是你的sql語句造成的嗎深员?看完這篇文章嗓违,我相信你會對sql優(yōu)化有了一定的了解入宦!

explain

通過查看sql執(zhí)行計劃來確定各部位的問題哺徊。使用方法:在sql語句前面加上explain關鍵字。

explain SELECT * FROM (SELECT id FROM sys_address where remarks='中國' or remarks='中國重慶'  or remarks='中國重慶重慶市' or remarks like '%渝北區(qū)%') a

執(zhí)行結(jié)果:

id select_type table partitions type possible_keys key key_len ref rows filtered Extr
1 SIMPLE sys_address ALL 667651 35.2 Using where

參數(shù)說明:

  • id

id值越大乾闰,優(yōu)先級越高落追,就越先執(zhí)行。如果id值一樣涯肩,那可以看成一組轿钠。

  • select_type

常見的值以及含義:

SIMPLE 簡單的select查詢,查詢中不包含子查詢或者UNION病苗。

PRIMARY 查詢中若包含任何復雜的子部分疗垛,最外層查詢則被標記為PRIMARY。

SUBQUERY 在SELECT或WHERE列表中包含了子查詢硫朦。

DERIVED 在FROM列表中包含的子查詢被標記為DERIVED(衍生)贷腕,MySQL會遞歸執(zhí)行這些子查詢,把結(jié)果放在臨時表中阵幸。

UNION 若第二個SELECT出現(xiàn)在UNION之后,則被標記為UNION:若UNION包含在FROM子句的子查詢中芽世,外層SELECT將被標記為:DERIVED挚赊。

UNION RESULT 從UNION表獲取結(jié)果的SELECT。

  • table

值就是當前執(zhí)行的表名济瓢。

  • partitions

  • type

**執(zhí)行效率 **system > const > eq_ref > ref > range > index > all

system:表僅有一行(=系統(tǒng)表)荠割。這是const聯(lián)接類型的一個特例。

const:表最多有一個匹配行旺矾,它將在查詢開始時被讀取蔑鹦。因為僅有一行,在這行的列值可被優(yōu)化器剩余部分認為是常數(shù)箕宙。

const用于用常數(shù)值比較PRIMARY KEY或UNIQUE索引的所有部分時嚎朽。

eq_ref:對于每個來自于前面的表的行組合,從該表中讀取一行柬帕。這可能是最好的聯(lián)接類型哟忍,除了const類型狡门。它用在一個索引

的所有部分被聯(lián)接使用并且索引是UNIQUE或PRIMARY KEY。eq_ref可以用于使用= 操作符比較的帶索引的列锅很。比較值可以為常量或

一個使用在該表前面所讀取的表的列的表達式其馏。

ref:對于每個來自于前面的表的行組合,所有有匹配索引值的行將從這張表中讀取爆安。如果聯(lián)接只使用鍵的最左邊的前綴叛复,或如

果鍵不是UNIQUE或PRIMARY KEY(換句話說,如果聯(lián)接不能基于關鍵字選擇單個行的話)扔仓,則使用ref褐奥。如果使用的鍵僅僅匹配少量

行,該聯(lián)接類型是不錯的当辐。ref可以用于使用=或<=>操作符的帶索引的列抖僵。

ref_or_null:該聯(lián)接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行缘揪。在解決子查詢中經(jīng)常使用該聯(lián)接類型的

優(yōu)化耍群。

index_merge:該聯(lián)接類型表示使用了索引合并優(yōu)化方法。在這種情況下找筝,key列包含了使用的索引的清單蹈垢,key_len包含了使

用的索引的最長的關鍵元素。

unique_subquery:該類型替換了下面形式的IN子查詢的ref:value IN (SELECT primary_key FROMsingle_table WHERE

some_expr);unique_subquery是一個索引查找函數(shù)袖裕,可以完全替換子查詢曹抬,效率更高。

index_subquery:該聯(lián)接類型類似于unique_subquery急鳄“瘢可以替換IN子查詢,但只適合下列形式的子查詢中的非唯一索引:

value IN (SELECT key_column FROM single_table WHERE some_expr)

range:只檢索給定范圍的行疾宏,使用一個索引來選擇行张足。key列顯示使用了哪個索引。key_len包含所使用索引的最長關鍵元素坎藐。

在該類型中ref列為NULL为牍。當使用=、<>岩馍、>碉咆、>=、<蛀恩、<=疫铜、IS NULL、<=>双谆、BETWEEN或者IN操作符块攒,用常量比較關鍵字列時励稳,

可以使用range。

  • possible_keys

possible_keys列指出MySQL能使用哪個索引在該表中找到行囱井。注意驹尼,該列完全獨立于EXPLAIN輸出所示的表的次序。這意味著

在possible_keys中的某些鍵實際上不能按生成的表次序使用庞呕。

  • key

key列顯示MySQL實際決定使用的鍵(索引)新翎。如果沒有選擇索引,鍵是NULL住练。要想強制MySQL使用或忽視possible_keys列中的

索引地啰,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX讲逛。

  • key_len

key_len列顯示MySQL決定使用的鍵長度亏吝。如果鍵是NULL,則長度為NULL盏混。注意通過key_len值我們可以確定MySQL將實際使

用一個多部關鍵字的幾個部分蔚鸥。

  • ref

ref列顯示使用哪個列或常數(shù)與key一起從表中選擇行。

  • rows

rows列顯示MySQL認為它執(zhí)行查詢時必須檢查的行數(shù)许赃。

  • filtered

  • Extr

該列包含MySQL解決查詢的詳細信息止喷。

Distinct:MySQL發(fā)現(xiàn)第1個匹配行后,停止為當前的行組合搜索更多的行混聊。

Not exists:MySQL能夠?qū)Σ樵冞M行LEFT JOIN優(yōu)化弹谁,發(fā)現(xiàn)1個匹配LEFT JOIN標準的行后,不再為前面的的行組合在該表內(nèi)檢

查更多的行句喜。

range checked for each record (index map: #):MySQL沒有發(fā)現(xiàn)好的可以使用的索引预愤,但發(fā)現(xiàn)如果來自前面的表的列值已

知,可能部分索引可以使用咳胃。對前面的表的每個行組合植康,MySQL檢查是否可以使用range或index_merge訪問方法來索取行。

Using filesort:MySQL需要額外的一次傳遞拙绊,以找出如何按排序順序檢索行向图。通過根據(jù)聯(lián)接類型瀏覽所有行并為所有匹配

WHERE子句的行保存排序關鍵字和行的指針來完成排序泳秀。然后關鍵字被排序标沪,并按排序順序檢索行。

Using index:從只使用索引樹中的信息而不需要進一步搜索讀取實際的行來檢索表中的列信息嗜傅。當查詢只使用作為單一索引一

部分的列時金句,可以使用該策略。

Using temporary:為了解決查詢吕嘀,MySQL需要創(chuàng)建一個臨時表來容納結(jié)果违寞。典型情況如查詢包含可以按不同情況列出列的

GROUP BY和ORDER BY子句時贞瞒。

Using where:WHERE子句用于限制哪一個行匹配下一個表或發(fā)送到客戶。除非你專門從表中索取或檢查所有行趁曼,如果Extra值

不為Using where并且表聯(lián)接類型為ALL或index军浆,查詢可能會有一些錯誤。

Using sort_union(...), Using union(...), Using intersect(...):這些函數(shù)說明如何為index_merge聯(lián)接類型合并索引掃描挡闰。

Using index for group-by:類似于訪問表的Using index方式乒融,Using index for group-by表示MySQL發(fā)現(xiàn)了一個索引,可

以用來查詢GROUP BY或DISTINCT查詢的所有列摄悯,而不要額外搜索硬盤訪問實際的表赞季。并且,按最有效的方式使用索引奢驯,以便對于

每個組申钩,只讀取少量索引條目。

索引

索引的作用就是加快查詢速度瘪阁,它就像書的目錄撒遣,當你想獲取到里面內(nèi)容位置時,就需要可以通過目錄快速的定位到具體位置罗洗。

首先我們需要明確一點愉舔,索引并不是越多越好。因為寫入數(shù)據(jù)時伙菜,會對索引字段進行一些處理轩缤,就會影響插入速度。

在MySql中的常用索引:

  • 主鍵索引

一個表中只有一個主鍵索引贩绕,一般在建表的時候就自動存在了火的。由系統(tǒng)自動創(chuàng)建,不需要額外手動創(chuàng)建淑倾。

  • 普通索引

一般索引馏鹤。

ALTER TABLE table_name ADD INDEX 索引名(column1,column2);
  • 唯一索引

表示列中不能有重復值。

ALTER TABLE `table_name` ADD UNIQUE (`column`)娇哆;
  • 全文索引

通常用于文本值中湃累,比如商品詳細信息等。

合理添加索引

  1. 查詢頻繁的字段碍讨,應該添加索引治力。

  2. 更新頻繁的字段,不應該添加索引勃黍。

  3. 唯一性太差的字段不應該添加索引宵统,比如sex性別字段。

索引失效

以下幾種情況覆获,即使字段創(chuàng)建了索引马澈,也不會使用到瓢省。

  1. like語句以“%”開頭。

  2. or語句的字段沒有全部使用索引痊班,其中任意一個沒有索引的話勤婚,此條件就不會使用索引。

  3. 在組合查詢中涤伐,第一個查詢字段的名稱不是復合索引中的第一列蛔六。

  4. 在索引列上使用IS NULL 或者IS NOT NULL,索引是不能索引空值的废亭,這樣的操作會導致全表掃描国章。

  5. 在索引字段上使用not 、<>豆村、!=液兽。

  6. 在索引字段上執(zhí)行函數(shù),如DATE_FORMAT(data, format)掌动。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末四啰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子粗恢,更是在濱河造成了極大的恐慌柑晒,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件眷射,死亡現(xiàn)場離奇詭異匙赞,居然都是意外死亡,警方通過查閱死者的電腦和手機妖碉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門涌庭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人欧宜,你說我怎么就攤上這事坐榆。” “怎么了冗茸?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵席镀,是天一觀的道長。 經(jīng)常有香客問我夏漱,道長豪诲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任麻蹋,我火速辦了婚禮跛溉,結(jié)果婚禮上焊切,老公的妹妹穿的比我還像新娘扮授。我一直安慰自己芳室,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布刹勃。 她就那樣靜靜地躺著堪侯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪荔仁。 梳的紋絲不亂的頭發(fā)上伍宦,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音乏梁,去河邊找鬼次洼。 笑死,一個胖子當著我的面吹牛遇骑,可吹牛的內(nèi)容都是我干的卖毁。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼落萎,長吁一口氣:“原來是場噩夢啊……” “哼亥啦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起练链,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤翔脱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后媒鼓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體届吁,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年绿鸣,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓷产。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡枚驻,死狀恐怖濒旦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情再登,我是刑警寧澤尔邓,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站锉矢,受9級特大地震影響梯嗽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沽损,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一灯节、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦炎疆、人聲如沸卡骂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽全跨。三九已至,卻和暖如春亿遂,著一層夾襖步出監(jiān)牢的瞬間浓若,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工蛇数, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留挪钓,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓耳舅,卻偏偏與公主長得像诵原,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挽放,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348