高性能MYSQL(四)

可以通過explain 語句來對查詢進(jìn)行查看.對可優(yōu)化的地方做出改進(jìn)

前言

優(yōu)化的主要組成部分:

  • 查詢語句的優(yōu)化
  • 索引設(shè)計(jì)的優(yōu)化
  • 庫表設(shè)計(jì)的優(yōu)化

一個(gè)查詢操作實(shí)際上是多個(gè)子任務(wù)組成,優(yōu)化查詢實(shí)際上是優(yōu)化子任務(wù)的執(zhí)行

  • 一個(gè)查詢的子任務(wù)清單:

    • 網(wǎng)絡(luò)IO
    • 磁盤IO
    • CPU計(jì)算
    • 互斥鎖等待

優(yōu)化數(shù)據(jù)訪問

避免存儲多余數(shù)據(jù)

  • 避免大量無用數(shù)據(jù)存在于數(shù)據(jù)表中,加大查詢語句的執(zhí)行復(fù)雜度
  • 避免大量無用的行

避免無用的查詢

  • 例如在分頁查詢時(shí),添加合適的LIMIT
  • 聯(lián)查時(shí)只取出有用的數(shù)據(jù)话原,避免下面的“一把抓“式的請求
SELECT * FROM A INNER JOIN B WHRER A.ID = B.A_ID
  • 按需取出響應(yīng)的列
  • 添加緩存
  • 在慢查詢?nèi)罩局性穸治鲆粋€(gè)查詢的查詢時(shí)間是否合理可以利用快速上限法進(jìn)行估量: 估算這個(gè)查詢大約會經(jīng)過的隨機(jī)IO數(shù) * 具體硬件下一次IO的時(shí)間,對查詢進(jìn)行估計(jì)
  • 優(yōu)化聯(lián)查!優(yōu)化聯(lián)查!聯(lián)查時(shí)掃描的行是 矩陣式的 M * N ,很恐怖鳖孤,所以找到好的對飲關(guān)系是優(yōu)化聯(lián)查的

重構(gòu)查詢時(shí)的方式

一個(gè)復(fù)雜的查詢還是多個(gè)簡單的查詢

對于mysql 來說岗憋,MYSQL從設(shè)計(jì)上讓連接和斷開鏈接都很輕量級,在返回一個(gè)小的查詢結(jié)果方面很高效。對于網(wǎng)絡(luò)鏈接來說現(xiàn)代網(wǎng)絡(luò)鏈接的效率相對與磁盤IO的效率來說已經(jīng)不是問題欢策。通常來將吆寨,兩者的區(qū)別不僅僅在于傳輸速度,磁盤IO在查詢時(shí)還有Lookup的過程踩寇。

對于復(fù)雜的查詢來說啄清,將其分解成多個(gè)簡單的查詢“乘铮或許效率更快些辣卒。但是同樣的,具場景具體分析

將復(fù)雜的操作切分帶來的另一個(gè)好處是可以分解復(fù)雜操作長時(shí)間對于讀/寫鎖長時(shí)間占有睛榄,從而避免影響其他業(yè)務(wù)操作的執(zhí)行

image.png
  1. 客戶端發(fā)送一條查詢給服務(wù)器
  2. 服務(wù)器首先查詢緩存荣茫。如果命中,則立即返回存儲在存儲在緩存中的結(jié)果场靴。否則進(jìn)入下一階段
  3. 服務(wù)器端進(jìn)行SQL解析啡莉,預(yù)處理,再由優(yōu)化器生成對應(yīng)的執(zhí)行計(jì)劃
  4. MYSQL根據(jù)優(yōu)化器生成的執(zhí)行計(jì)劃旨剥,調(diào)用存儲引擎的API來執(zhí)行查詢
  5. 將結(jié)果集返回給客戶端

MYSQL 客戶端和服務(wù)器端通信

總的來說咧欣,MYSQL客戶端和服務(wù)器端是一個(gè)半雙工的通信狀態(tài),也就是說轨帜,在同一個(gè)時(shí)間魄咕,只能有一端像另一端發(fā)送數(shù)據(jù)(不要被JDBC的線程池的概念混淆)

SHOW ALL PROCESSLIST

各個(gè)MYSQL鏈接對應(yīng)的狀態(tài) :

  • SLEEP : 線程正在等待客戶端發(fā)送新的請求
  • QUERY : 線程正在執(zhí)行查詢或者正在將結(jié)果發(fā)送給客戶端
  • LOCKED : 線程正在等待表鎖
  • Sending Data : 這表示多種情況: 線程可能在多個(gè)狀態(tài)之間傳送數(shù)據(jù),或者在 生成結(jié)果集阵谚,或者在客戶端返回?cái)?shù)據(jù)

查詢緩存

查詢緩存是通過一個(gè)對 大小寫敏感的哈希查找實(shí)現(xiàn)的蚕礼。如果緩存中緩存有對應(yīng)數(shù)據(jù)。數(shù)據(jù)會直接返回給客戶端梢什。

  • 上面的這個(gè)大小寫敏感奠蹬,不代表SQL語法關(guān)鍵字敏感。
  • 雖然語法檢查在查詢緩存之后嗡午,但是你可以考慮到這一點(diǎn)囤躁。語法錯(cuò)誤的查詢在第一次執(zhí)行的就沒成功,就不會有緩存荔睹!

查詢處理優(yōu)化

查詢的下一周期是將一個(gè)SQL 轉(zhuǎn)換為一個(gè)執(zhí)行計(jì)劃狸演,MYSQL再依照這個(gè)計(jì)劃和存儲引擎進(jìn)行交互。這包括多個(gè)子階段:解析SQL僻他,預(yù)處理宵距,優(yōu)化SQL執(zhí)行計(jì)劃。

語法解析器和預(yù)處理

階段所做工作

  • 語法解析器負(fù)責(zé)語法檢查
  • 預(yù)處理器根據(jù)MYSQL規(guī)則 進(jìn)一步檢查 解析樹是否合法吨拗,例如檢查數(shù)據(jù)表和數(shù)據(jù)列是否存在满哪,還會解析名字和別名婿斥,看他們是否有歧義

查詢優(yōu)化器

  • 可以通過 show status like 'Last_query_cost'的值來得知MYSQL計(jì)算的當(dāng)前查詢的成本
explain SELECT * FROM commonservice.regions where amapid is not  null;

show  status like 'Last_query_ cost'
Variable_name Value
'Last_query_cost' '142998.599000'

上面的查詢結(jié)果上面的查詢需要 142998個(gè)數(shù)據(jù)頁的隨機(jī)查找才能完成這個(gè)查詢。當(dāng)然這只是查詢優(yōu)化器的評估結(jié)果哨鸭,且優(yōu)化器在評估時(shí)不會考拉

  • 影響MYSQL 錯(cuò)誤選擇執(zhí)行計(jì)劃的因素

    • 統(tǒng)計(jì)信息不準(zhǔn)確民宿,例如:InnoDB因?yàn)槠?a target="_blank" rel="nofollow">MVCC的架構(gòu),并不能維護(hù)一個(gè)數(shù)據(jù)表的行數(shù)的精確統(tǒng)計(jì)信息
    • 執(zhí)行計(jì)劃中的成本估算不等于實(shí)際執(zhí)行計(jì)劃,也就是說優(yōu)化器給出的執(zhí)行計(jì)劃也可能不是最優(yōu)的像鸡,比如說活鹰,有些頁面讀取雖多,但是其頁面大部分都是順序讀寫只估。
    • MYSQL 從不考慮其他并發(fā)執(zhí)行的查詢志群,這可能會影響當(dāng)前查詢速度
      MYSQL 的查詢優(yōu)化的優(yōu)化策略分為兩種
  • 靜態(tài)優(yōu)化 : 靜態(tài)優(yōu)化不依賴于特別的數(shù)值,如WHERE 條件中帶入的一些常數(shù)等仅乓,靜態(tài)優(yōu)化在第一次完成后就一直有效赖舟,即使使用不同的參數(shù)重復(fù)查詢也不會發(fā)生變化,可以將靜態(tài)優(yōu)化認(rèn)為是一種 “編譯時(shí)優(yōu)化”

  • 動態(tài)優(yōu)化 : 動態(tài)優(yōu)化則和查詢的上下文有關(guān)夸楣,例如WHERE 條件中的取值宾抓,索引中條目對應(yīng)的數(shù)據(jù)行數(shù)等,這需要在每次查詢的時(shí)候重新評估 可以將動態(tài)優(yōu)化認(rèn)為是一種”運(yùn)行時(shí)優(yōu)化“

MYSQL能夠優(yōu)化的的類型

重新定義關(guān)聯(lián)表的順序 : 數(shù)據(jù)表的關(guān)聯(lián)并不是按照在查詢中指定的順序執(zhí)行
將外鏈接轉(zhuǎn)換為內(nèi)鏈接 : 并不是所有的OUTER JOIN 語句都必須以外鏈接的方式執(zhí)行豫喧。例如石洗,WHERE條件,庫表結(jié)構(gòu)都可能會讓外鏈接等價(jià)于一個(gè)內(nèi)連接

  • 使用等價(jià)變換規(guī)則 利用等價(jià)變換來簡化病規(guī)范表達(dá)式
  • 優(yōu)化COUNT() ,MIN() ,MAX() : 通過B-Tree索引 直接查找其中的一個(gè)方向
  • **預(yù)估并轉(zhuǎn)化為常數(shù)表達(dá)式 : **
  • 覆蓋索引掃描 : 當(dāng)索引中的列包含查詢中需要的列紧显,MYSQL會直接返回索引對應(yīng)的列讲衫,不再去查表
  • **子查詢優(yōu)化 : ** Mysql 在某些情況下可以將子查詢轉(zhuǎn)換為一種效率更高的形式,從而減少多個(gè)查詢對數(shù)據(jù)進(jìn)行訪問
  • 提前終止查詢: 當(dāng)發(fā)現(xiàn)已經(jīng)滿足查詢需求的時(shí)候孵班,MYSQL 總是能夠立刻終止查詢涉兽。比如使用LIMIT語句或者發(fā)現(xiàn)了一個(gè)不成立的條件,這時(shí)候MYSQL會立即返回一個(gè)空結(jié)果
  • 列表IN ()的優(yōu)化 : ** 在MYSQL 中篙程,MYSQL首選將IN()列表中的數(shù)據(jù)先進(jìn)行排序枷畏,然后通過二分查找的方式來確定列表中的值是否滿足條件(時(shí)間復(fù)雜度 : O(lgN) ),如果等價(jià)的轉(zhuǎn)換為OR操作的話,時(shí)間復(fù)雜度為 O(n) :所以說 單列 多值匹配時(shí)虱饿,利用IN () 效率會更高**

Mysql 如果執(zhí)行關(guān)聯(lián)查詢

  • 對于UNION查詢拥诡,MYSQL先將一系列的單個(gè)查詢結(jié)果放到一個(gè)臨時(shí)表中,然后再讀出臨時(shí)表中數(shù)據(jù)完成UNION查詢

執(zhí)行計(jì)劃 : MYSQL 并不會生成查詢字節(jié)碼來執(zhí)行查詢氮发。MYSQL生成查詢的一顆指令樹渴肉,然后通過存儲引擎執(zhí)行完成這可指令樹并返回結(jié)果。最終執(zhí)行計(jì)劃包含了重構(gòu)查詢的全部信息

優(yōu)化特定類型的查詢

優(yōu)化COUNT()查詢
  1. 如果想要查詢行數(shù)爽冕,使用count() 進(jìn)行查詢仇祭,如果在count()函數(shù)中指定了某列,查詢的是這個(gè)列有值(非 NULL)的值的個(gè)數(shù)颈畸!
優(yōu)化關(guān)聯(lián)查詢
  1. 確保ON或者USING 子句的列上有索引乌奇,一般來說嚣艇,除非有其他理由,否則只需要在關(guān)聯(lián)順序中的第二個(gè)表上建立索引
  2. 確保仁和Group by 或者Order by中的表達(dá)式只涉及到一個(gè)表中的列
GROUP By 和 DISTINCT
  1. 在無法使用索引的時(shí)候华弓,GROUP BY使用臨時(shí)表或者文件排序來分組
  2. 如果需要對 關(guān)聯(lián)查詢做分組,并且是按照查找表中的某個(gè)列進(jìn)行分組困乒,那么通常采用查找表的標(biāo)識列分組的效率比其他列更高
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寂屏,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子娜搂,更是在濱河造成了極大的恐慌迁霎,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件百宇,死亡現(xiàn)場離奇詭異考廉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)携御,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門昌粤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人啄刹,你說我怎么就攤上這事涮坐。” “怎么了誓军?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵袱讹,是天一觀的道長。 經(jīng)常有香客問我昵时,道長捷雕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任壹甥,我火速辦了婚禮救巷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盹廷。我一直安慰自己征绸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布俄占。 她就那樣靜靜地躺著管怠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缸榄。 梳的紋絲不亂的頭發(fā)上渤弛,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機(jī)與錄音甚带,去河邊找鬼她肯。 笑死佳头,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晴氨。 我是一名探鬼主播康嘉,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼籽前!你這毒婦竟也來了亭珍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤枝哄,失蹤者是張志新(化名)和其女友劉穎肄梨,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挠锥,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡众羡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蓖租。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粱侣。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖菜秦,靈堂內(nèi)的尸體忽然破棺而出甜害,到底是詐尸還是另有隱情,我是刑警寧澤球昨,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布尔店,位于F島的核電站,受9級特大地震影響主慰,放射性物質(zhì)發(fā)生泄漏嚣州。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一共螺、第九天 我趴在偏房一處隱蔽的房頂上張望该肴。 院中可真熱鬧,春花似錦藐不、人聲如沸匀哄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涎嚼。三九已至,卻和暖如春挑秉,著一層夾襖步出監(jiān)牢的瞬間法梯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留立哑,地道東北人夜惭。 一個(gè)月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像铛绰,于是被迫代替她去往敵國和親诈茧。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

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

  • 國慶第二天,今天嗨翻模式的開啟就等室友的同學(xué)來了再說吧尘颓,在這之前,先來一波筆記 查詢真正重要的是響應(yīng)時(shí)間晦譬,查詢包含...
    小煉君閱讀 1,715評論 0 50
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理疤苹,服務(wù)發(fā)現(xiàn),斷路器敛腌,智...
    卡卡羅2017閱讀 134,704評論 18 139
  • 《高性能MySQL》&《MySQL技術(shù)內(nèi)幕 InnoDB存儲引擎》筆記 第一章 MySQL架構(gòu)與歷史 MySQL的...
    xiaogmail閱讀 12,777評論 0 39
  • 2017年元旦前后在虹橋機(jī)場書店里買了三本雜志:商業(yè)周刊中文版總371期卧土,第一財(cái)經(jīng)周刊總435期,鳳凰周刊總601...
    天光閱讀 290評論 0 1
  • 看了些別人隨便寫寫的想法和感受,我發(fā)現(xiàn)生棍,應(yīng)該是都有各自的特色吧颤霎。但,我好像是不太會吧涂滴?不太會把自己的想法或感受用文...
    一半天空_fly閱讀 272評論 -1 1