本篇深入了解查詢(xún)優(yōu)化和服務(wù)器的內(nèi)部機(jī)制,了解MySql如何執(zhí)行特定查詢(xún),從中也可以知道如何更改查詢(xún)執(zhí)行計(jì)劃,當(dāng)我們深入理解MySql如何真正地執(zhí)行查詢(xún),明白高效和低效的真正含義,在實(shí)際應(yīng)用中就能揚(yáng)長(zhǎng)避短。
聲明:本人使用的數(shù)據(jù)庫(kù)版本為MySql 5.1
一、基本原則:優(yōu)化數(shù)據(jù)訪問(wèn)
查詢(xún)性能低下的最基本原因就是訪問(wèn)了太多數(shù)據(jù),一些查詢(xún)要不可避免地篩選大量的數(shù)據(jù),大部分性能欠佳的查詢(xún)都可以用減少數(shù)據(jù)訪問(wèn)的方式進(jìn)行優(yōu)化。
1、首先分析應(yīng)用程序是否正在獲取超過(guò)需要的數(shù)據(jù),這通常表現(xiàn)在獲取了過(guò)多的行或列。一些查詢(xún)先向服務(wù)器請(qǐng)求不需要的數(shù)據(jù),再丟掉他們,這個(gè)讓服務(wù)器造成了額外的負(fù)擔(dān),增加了網(wǎng)絡(luò)開(kāi)銷(xiāo),消耗了內(nèi)存和CPU資源。
> 如果前臺(tái)只需要顯示15條數(shù)據(jù),而你的查詢(xún)結(jié)果集返回了100條,則要想想是否真有必要這樣干了,最好使用LIMIT來(lái)限制查詢(xún)的條數(shù)。
> 盡量避免使用SELECT * , 也許你并不需要所有的列,但獲取所有的列將會(huì)造成覆蓋索引這樣的優(yōu)化手段失效,也會(huì)增加磁盤(pán)I/O、內(nèi)存和CPU的開(kāi)銷(xiāo)等,所以基于這種情況,盡量使用SELECT t.id, t.name ... 這種查詢(xún)具體字段的SQL。
但是,SELECT * 這種稍顯浪費(fèi)的方式可以簡(jiǎn)化開(kāi)發(fā),增加代碼的復(fù)用性(比如以后擴(kuò)展了字段,就不用再改sql代碼了)。
如果系統(tǒng)使用了持久化框架,而我們只查詢(xún)了某一些字段出來(lái),然后再直接去更新這個(gè)持久化對(duì)象時(shí),那些未查詢(xún)出來(lái)的字段就會(huì)被設(shè)置為NULL,導(dǎo)致數(shù)據(jù)丟失。所以,如果只查詢(xún)一部分字段,要避免去更新持久化對(duì)象(親身經(jīng)歷)。
在程序中,還是倡導(dǎo)使用SELECT t.id, t.name ... 這種形式,能更好地利用索引;如果只是顯示數(shù)據(jù),那就按需查詢(xún)部分字段即可,這樣能更充分利用覆蓋索引;如果需要更新數(shù)據(jù),則必須查詢(xún)出所有字段。
2、其次看是否檢查了過(guò)多的數(shù)據(jù),一般從查詢(xún)的執(zhí)行時(shí)間、檢查的行數(shù)、返回的行數(shù)來(lái)看,但這些不可作為絕對(duì)的標(biāo)準(zhǔn)。
> 看下面的這個(gè)執(zhí)行計(jì)劃:
第一幅圖中:key表明使用了id_card索引;rows=1,表明只檢查了一行數(shù)據(jù),所以其速度是很快的。
第二幅圖中:刪除了索引后的執(zhí)行計(jì)劃,沒(méi)有使用索引,檢查的行數(shù)是81697,而我們只需要一行數(shù)據(jù);而如果數(shù)據(jù)量不斷增加,再與其它表關(guān)聯(lián)查詢(xún)的話,其性能可想而知是有多低效。
所以,查看是否檢查了過(guò)多的行,使用一些優(yōu)化手段如利用好索引或者重構(gòu)查詢(xún)盡量去減少檢查的行數(shù)。
> 再看下面這個(gè)執(zhí)行計(jì)劃:
這個(gè)查詢(xún)聯(lián)接了多張表,僅第一張表就檢查了10W行(而我們只需要15行),然后再與其它表進(jìn)行聯(lián)接,再排序,效率自然低下了。而其它檢查出只有一行的表,可看出其使用了索引列進(jìn)行聯(lián)接,可見(jiàn)使用好索引的高效。
看第二幅圖:使用了一個(gè)子查詢(xún)以減少檢查的行數(shù),加上id列本身是排好序的,所以Extra列可以看到?jīng)]有使用臨時(shí)表進(jìn)行文件排序了,在第一幅圖中,使用臨時(shí)表排序(using temporyary,using filesort)是很耗時(shí)的。
延伸閱讀
- ssh框架 2016-09-30
- 阿里移動(dòng)安全 [無(wú)線安全]玩轉(zhuǎn)無(wú)線電——不安全的藍(lán)牙鎖 2017-07-26
- 消息隊(duì)列NetMQ 原理分析4-Socket、Session、Option和Pipe 2024-03-26
- Selective Search for Object Recognition 論文筆記【圖片目標(biāo)分割】 2017-07-26
- 詞向量-LRWE模型-更好地識(shí)別反義詞同義詞 2017-07-26
- 從棧不平衡問(wèn)題 理解 calling convention 2017-07-26
- php imagemagick 處理 圖片剪切、壓縮、合并、插入文本、背景色透明 2017-07-26
- Swift實(shí)現(xiàn)JSON轉(zhuǎn)Model - HandyJSON使用講解 2017-07-26
- 阿里移動(dòng)安全 Android端惡意鎖屏勒索應(yīng)用分析 2017-07-26
- 集合結(jié)合數(shù)據(jù)結(jié)構(gòu)來(lái)看看(二) 2017-07-26