一些典型案例如下:
1. 查詢不需要的記錄
這是一個常見的錯誤,常常會誤以為MySQL只會返回需要的數(shù)據(jù),實際上MySQL卻是先返回全部結果集再進行計算。
開發(fā)者習慣性的先使用SELECT語句查詢大量的結果,然后由應用查詢或者前端展示層再獲取前面的N行數(shù)據(jù),例如,在新聞網(wǎng)站中查詢100條記錄,但是只是在頁面上顯示前10條。
最有效的解決方法是需要多少記錄就查詢多少記錄,通常會在查詢后面加上LIMIT,即: 分頁查詢。
2. 多表關聯(lián)時返回全部列
如果你想查詢所有在電影Academy Dinosaur中出現(xiàn)的演員,千萬不要按下面的方式來進行查詢:
select * fromt actor a inner join film_actor fa.actorId = a.actorId inner join film f f.filmId = fa.filmId where fa.title = 'Academy Dinosaur';
這樣將會返回三張表的全部數(shù)據(jù)列,而實際需求是要查詢演員信息,正確的寫法應該是:
select a.* fromt actor a inner join film_actor fa.actorId = a.actorId inner join film f f.filmId = fa.filmId where fa.title = 'Academy Dinosaur';
3. 總是查詢出全部列
每次看到select *的時候一定要用異樣的目光來審視它,是不是真的需要返回全部數(shù)據(jù)列?
在大部分情況下,是不需要的。 select *會導致進行全表掃描,會讓優(yōu)化器無法完成索引掃描這類優(yōu)化,過多的列還會為服務器帶來額外的I/O、內(nèi)存和CPU的消耗。 即使真的需要查詢出全部列,應該逐個羅列出全部列而不是*。
4. 重復查詢相同的數(shù)據(jù)
如果你不太留意,很容易出現(xiàn)這樣的錯誤: 不斷地重復執(zhí)行相同的查詢,然后每次都返回完全相同的數(shù)據(jù)。
例如,在用戶評論的地方需要查詢用戶頭像的URL,那么用戶多次評論的時候,可能就會反復來查詢這個數(shù)據(jù)。 比較好處理方法是,在初次查詢的時候?qū)⑦@個數(shù)據(jù)緩存起來,后續(xù)使用時直接從緩存中取出。
三、是否掃描了額外的記錄
確 定查詢只查詢了需要的數(shù)據(jù)以后,接下來應該看看查詢過程中是否掃描了過多的數(shù)據(jù)。 對于MySQL,最簡單衡量查詢開銷的三個指標如下:
響應時間掃描的行數(shù)返回的行數(shù)
沒有哪個指標能夠完全來衡量查詢的開銷,但它們能夠大致反映MySQL內(nèi)部執(zhí)行查詢時需要訪問多少數(shù)據(jù),并可以大概推算出查詢運行的實際。 這三個指標都會記錄到MySQL的慢日志中,所以 檢查慢日志記錄是找出掃描行數(shù)過多查詢的辦法 。
慢查詢: 用于記錄在MySQL中響應時間超過閾值(long_query_time,默認10s)的語句,并會將慢查詢記錄到慢日志中。 可通過變量slow_query_long來開啟慢查詢,默認是關閉狀態(tài),可以將慢日志記錄到表slow_log或文件中,以供檢查分析。
1. 響應時間
響應時間是兩個部分之和: 服務時間和排隊時間。 服務時間是指數(shù)據(jù)庫處理這個查詢真正花費了多長時間。 排隊時間是指服務器因為等待某些資源而沒有真正執(zhí)行查詢的時間,可能是等待I/O操作,也可能是等待 行 鎖等等。
在不同類型的應用壓力下,響應時間并沒有什么一致的規(guī)律或者公式。 諸如存儲引擎的鎖(表鎖,行鎖),高并發(fā)資源競爭,硬件響應等諸多因素都會影響響應時間,所以,響應時間既可能是一個問題的結果也可能是一個問題的原因,不同案例情況不同。
當你看到一個查詢的響應時間的時候,首先需要問問自己,這個響應時間是否是一個合理的值。
2. 掃描的行數(shù)和返回的行數(shù)
在分析查詢時,查看該查詢掃描的行數(shù)是非常有幫助的,在此之上也能夠分析是否掃描了額外的記錄。
對于找出那些糟糕查詢,這個指標可能還不夠完美,因為并不是所有行的訪問代價都是相同的。 較短的行的訪問速度相當快,內(nèi)存中的行也比磁盤中的行的訪問速度要快的多。
理想的情況下,掃描的行數(shù)和返回的行數(shù)應該是相同的。 但實際上這種美事并不多,例如在做一個關聯(lián)查詢的時候,掃描的行數(shù)和對返回的行數(shù)的比率通常都很小,一般在1:1和10:1之間,不過有時候這個值也可能非常大。
3. 掃描的行數(shù)和訪問類型
在評估查詢開銷的時候,需要考慮一下從表中找到某一行數(shù)據(jù)的成本。 MySQL有好幾種訪問方式可以查找并返回一行結果。 這些訪問方式可能需要訪問很多行才能返回一條結果,也有些訪問方式可能無需掃描就能返回結果。
在執(zhí)行計劃EXPLAIN語句中的type列反映了訪問類型。 訪問類型有很多種,從全表掃描到索引掃描,范圍掃描,唯一索引,常數(shù)索引等。 這里列的這些,速度是從慢到快,掃描的行數(shù)也是從多到少。
如果查詢沒有辦法找到合適的訪問類型,那么解決的最好辦法通常就是增加一個合適的索引,這也是我們之前討論索引的問題。 現(xiàn)在應該明白為什么索引對于查詢優(yōu)化如此重要了。 索引讓MySQL以最高效,掃描行數(shù)最少的方式找到需要的記錄 。
如果發(fā)現(xiàn)查詢掃描了大量的數(shù)據(jù)但只返回少數(shù)的行,通??梢試L試下面的技巧去優(yōu)化它:
使用索引覆蓋掃描,把所有需要用的列都放到索引中,這樣存儲引擎無需回表獲取對應的行就可以返回結果了。
優(yōu)化表結構。 例如使用單獨的匯總表來完成查詢。重寫復雜查詢,讓MySQL優(yōu)化器能夠以更優(yōu)化的方式執(zhí)行這個查詢。
相關推薦:編程視頻課程
更多關于云服務器,域名注冊,虛擬主機的問題,請訪問西部數(shù)碼官網(wǎng):m.ps-sw.cn