減少查詢的影響結(jié)果集,避免出現(xiàn)全表掃描。 影響結(jié)果集是SQL優(yōu)化的核心。影響結(jié)果集不是查詢返回的記錄數(shù),而是查詢所掃描的結(jié)果數(shù)。通過Explain或Desc分析SQL,rows列的值即為影響結(jié)果集(還可以通過慢查詢?nèi)罩镜腞ows_examined后面的數(shù)字得到)。 以下是我常用的一些SQL優(yōu)化策略:
不使用任何連表查詢,通過分庫和分表實(shí)現(xiàn)負(fù)載均衡。 隨著數(shù)據(jù)量的增加,連表操作往往會(huì)導(dǎo)致影響結(jié)果集大增,從SQL優(yōu)化的層面已經(jīng)解決不了問題了。 此時(shí),分庫和分表是解決數(shù)據(jù)庫性能壓力的最優(yōu)選擇(具體分庫和分表的方案通常結(jié)合實(shí)際業(yè)務(wù)的應(yīng)用場(chǎng)景來確定,此處略過)。這里重點(diǎn)談,如何更好的實(shí)現(xiàn)或者過渡到分庫、分表的分布式數(shù)據(jù)庫架構(gòu)。 核心點(diǎn)就是必須先去除數(shù)據(jù)表之間的關(guān)聯(lián),即不用外鍵,不使用任何連表查詢。為了確保不進(jìn)行連表操作,在設(shè)計(jì)數(shù)據(jù)庫表結(jié)構(gòu)的時(shí)候,就需要設(shè)計(jì)適度冗余的字段來達(dá)到不連表的目的。 對(duì)于一些操作日志、支付記錄等,設(shè)計(jì)一些記錄用戶信息的字段,個(gè)人認(rèn)為其實(shí)不能算冗余,畢竟用戶信息往往會(huì)更改,但是這種類似操作日志的表確實(shí)是需要記錄用戶操作時(shí)的信息,并且不需要在用戶更新信息時(shí)同步更新。 實(shí)際開發(fā)中,為了實(shí)現(xiàn)不進(jìn)行連表而冗余的字段,往往是需要在原表更新數(shù)據(jù)的時(shí)候同步更新冗余字段的數(shù)據(jù)的,如果應(yīng)用層沒有對(duì)數(shù)據(jù)表操作做合理封裝,這往往是個(gè)棘手的問題,也不方便維護(hù)。 當(dāng)然,現(xiàn)在主流的應(yīng)用框架,一般采用orm的方式處理數(shù)據(jù)表,所以問題不大。相反,不連表事實(shí)上還可以提高開發(fā)效率,比如通過用戶ID獲取用戶姓名操作,如果不連表就可以確保各個(gè)業(yè)務(wù)模塊都通過同樣的方式去獲取用戶姓名,調(diào)用同一個(gè)封裝好的方法,這樣,就能很方便的統(tǒng)一在應(yīng)用層加入緩存機(jī)制或添加統(tǒng)一的業(yè)務(wù)邏輯。 同時(shí)如果要對(duì)用戶表進(jìn)行分庫分表,通過應(yīng)用層程序就可以簡(jiǎn)單平滑的實(shí)現(xiàn)。 使用Innodb。 關(guān)于Innodb和Myisam對(duì)比,我就不多說了。Myisam的表級(jí)鎖是致命問題,考慮到MySQL已經(jīng)默認(rèn)使用Innodb作為數(shù)據(jù)庫引擎,個(gè)人建議大部分情況可以直接使用Innodb,其他引擎這里就不詳細(xì)討論了。這里有交流學(xué)習(xí)群:744642380里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化這些成為架構(gòu)師必備的知識(shí)體系。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源,目前受益良多 使用緩存。 1) 盡可能在程序上實(shí)現(xiàn)常用數(shù)據(jù)的緩存,目前主流的應(yīng)用框架應(yīng)該都能快速實(shí)現(xiàn)緩存的需求。如果在程序上沒有實(shí)現(xiàn)數(shù)據(jù)緩存,開啟數(shù)據(jù)庫的query cache也是緩解數(shù)據(jù)庫壓力的方式之一,如果確認(rèn)使用,記得定時(shí)清理碎片flush query cache。 服務(wù)器相關(guān)優(yōu)化 MySQL服務(wù)配置以及分布式架構(gòu)的實(shí)現(xiàn),請(qǐng)根據(jù)實(shí)際應(yīng)用場(chǎng)景和業(yè)務(wù)需求定制,非本文重點(diǎn),不做深入探討。 |
|