MySQL數(shù)據(jù)庫優(yōu)化(五)—MySQL查詢優(yōu)化

一、mysql查詢類型(默認查詢出所有數(shù)據(jù)列)
1、內(nèi)連接?
? ? ?默認多表關(guān)聯(lián)查詢方式,查詢出兩個表中所有字段;可省略inner join 關(guān)鍵字
2、外連接 查詢出某一張表中的所有數(shù)據(jù)
(1)左連接
? ? ? 查詢出第一張表的所有字段
(2)右連接
?查詢出第二張表的所有字段,表一匹配數(shù)據(jù)為空的返回null

3、子連接

--內(nèi)連接??查詢出bookID=book類型ID的記錄??  SELECT?tb.bookName,tby.bookTypeName?FROM?t_book?tb,t_bookType?tby?WHERE?tb.bookTypeId=tby.id;    --外連接(左連接)  SELECT??tb.bookName,tby.bookTypeName?FROM?t_book?LEFT?JOIN?t_bookType?ON?t_book.bookTypeId=t_bookType.id?where?......;  --外連接(右連接)  SELECT??tb.bookName,tby.bookTypeName?FROM?t_book?RIGHT?JOIN?t_bookType?ON?t_book.bookTypeId=t_bookType.id?where?......;    --子查詢  SELECT?*?FROM?t_book?WHERE?booktypeId?IN?(SELECT?id?FROM?t_booktype);  SELECT?*?FROM?t_book?WHERE?booktypeId?NOT?IN?(SELECT?id?FROM?t_booktype);  SELECT?*?FROM?t_book?WHERE?price>=(SELECT?price?FROM?t_pricelevel?WHERE?priceLevel=1);  SELECT?*?FROM?t_book?WHERE?EXISTS?(SELECT?*?FROM?t_booktype);  SELECT?*?FROM?t_book?WHERE?NOT?EXISTS?(SELECT?*?FROM?t_booktype);  SELECT?*?FROM?t_book?WHERE?price>=?ANY?(SELECT?price?FROM?t_pricelevel);  SELECT?*?FROM?t_book?WHERE?price>=?ALL?(SELECT?price?FROM?t_pricelevel);

二、查詢優(yōu)化思路
1、為什么會慢?
? ? ?在嘗試做查詢優(yōu)化之前,得明白是什么讓查詢變慢?如果把查詢看作一個由n個子任務(wù)組成的任務(wù),隨著子任務(wù)增多,sql關(guān)聯(lián)查詢也增多;優(yōu)化查詢,實際上就是優(yōu)化這n個子任務(wù),要么消除一些子任務(wù),要么減少子任務(wù)執(zhí)行次數(shù)。
2、有哪些子任務(wù)?
? ? ?mysql執(zhí)行一個查詢一般有這么幾個流程:客戶端發(fā)送查詢語句到服務(wù)端——>服務(wù)器解析查詢語句——>生成執(zhí)行計劃——>執(zhí)行查詢;其中執(zhí)行時整個生命周期最重要的階段,其中包括對數(shù)據(jù)庫引擎的調(diào)用、排序、分組的數(shù)據(jù)處理過程。
三、優(yōu)化方向
1、優(yōu)化查詢數(shù)據(jù)
? ? ?低效的查詢基本原因:訪問請求的數(shù)據(jù)太多,不可避免的需要進行大量篩選工作;
? ? ?錯誤嘗試:

select?*?from?t_user?t?inner?join?t_role?r?inner?join?t_permission?p?where?.....

? ? ?錯誤原因:使用內(nèi)連接,查詢出三個表中的所有數(shù)據(jù)列
? ? ?正確方式:

select?t.name,r.rolename,p.pname?from?t_user?t?inner?join?t_role?r?inner?join?t_permission?p?where

2、切分查詢
?? ? ?分而治之,將復(fù)雜的查詢切分成小查詢,每次查詢只返回一小部分結(jié)果
?? ? ?錯誤嘗試:

select?*?from?t_user?t?where?createData>DATE_SUB(NOW(),INTERVAL?3?MONTH)  ???????????????????????delete?from?t_user?t?where?createData>DATE_SUB(NOW(),INTERVAL?3?MONTH)

? ? ?錯誤原因:當(dāng)user表中數(shù)據(jù)量巨大時,一次性查詢或刪除表中大量數(shù)據(jù)均會導(dǎo)致等待停頓;
? ? ?正確方式:

select?*?from?t_user?t??where?createData>DATE_SUB(NOW(),INTERVAL?3?MONTH)??limit?0,1000;

? ? ? ? ? ? ? ? ? ? ?先查詢表中符合條件的前一1000條數(shù)據(jù);
3、分解關(guān)聯(lián)查詢
?? ? ?錯誤嘗試:

select?t.name,r.rolename,p.pname?from?t_user?t?inner?join?t_role?r?inner?join?t_permission?p?where

?? ? ?錯誤原因:當(dāng)user表中數(shù)據(jù)量巨大時,一次性查詢或刪除表中大量數(shù)據(jù)均會導(dǎo)致等待停頓;
? ? ??正確方式:

select?*?from?t_user?where??t.age=10;  ???????????????????????select?t.?rolename?from?t_user?where?...  ???????????????????????select?t.?pname?from?t_user?where?...

? ? ? ?分解關(guān)聯(lián)查詢表面上好像原本1個sql就干完的事,現(xiàn)在非得由3個sql去完成,實際上它比關(guān)聯(lián)查詢更有優(yōu)勢:
(1)提高緩存效率:對于第一條查詢中age=10這條記錄的所有字段已經(jīng)緩存在mysql中,供第二個查詢語句使用
(2)減少單個查詢間的鎖競爭
(3)減少冗余字段的查詢 ? ?
?
四、總結(jié)
? ? ?在平時的應(yīng)用中,尤其在在java開發(fā)提供了良好的數(shù)據(jù)持久化框架,對于mysql的查詢優(yōu)化并未過分關(guān)系,并且在使用sql執(zhí)行查詢時,可能也經(jīng)常使用到多表關(guān)聯(lián)查詢,在使用這些sql拼接的過程中,對于sql優(yōu)化不能不知曉,在應(yīng)對高并發(fā)問題中,除了在web服務(wù)器前做負載、平行擴展等措施之外,數(shù)據(jù)庫高并發(fā)的解決方案也與其并重,而這一個一個sql就是應(yīng)多高并發(fā)的優(yōu)化基礎(chǔ),不容小覷。 ?

?以上就是MySQL數(shù)據(jù)庫優(yōu)化(五)—MySQL查詢優(yōu)化的內(nèi)容,更多相關(guān)內(nèi)容請關(guān)注PHP中文網(wǎng)(www.php.cn)!

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊13 分享