本篇深入了解查詢(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ù)。

  大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

  > 再看下面這個(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í)的。

  大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

延伸閱讀

學(xué)習(xí)是年輕人改變自己的最好方式-Java培訓(xùn),做最負(fù)責(zé)任的教育,學(xué)習(xí)改變命運(yùn),軟件學(xué)習(xí),再就業(yè),大學(xué)生如何就業(yè),幫大學(xué)生找到好工作,lphotoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開(kāi)發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)學(xué)習(xí)是年輕人改變自己的最好方式