mysql优化三
相對高并發(fā)一樣,速度都是優(yōu)化出來的,在高并發(fā)處理的時候,通常采用的是redis緩存,全文搜索引擎,數(shù)據(jù)庫本身優(yōu)化,sql優(yōu)化,磁盤優(yōu)化
看如下圖:
所以可以得出的思想就是:
這個優(yōu)化法則歸納為5個層次:
1、 減少數(shù)據(jù)訪問(減少磁盤訪問)
2、 返回更少數(shù)據(jù)(減少網(wǎng)絡(luò)傳輸或磁盤訪問)
3、 減少交互次數(shù)(減少網(wǎng)絡(luò)傳輸)
4、 減少服務(wù)器CPU開銷(減少CPU及內(nèi)存開銷)
5、 利用更多資源(增加資源)
1、減少數(shù)據(jù)訪問
1.1、創(chuàng)建并使用正確的索引
數(shù)據(jù)庫索引的原理非常簡單,但在復(fù)雜的表中真正能正確使用索引的人很少,即使是專業(yè)的DBA也不一定能完全做到最優(yōu)。
索引會大大增加表記錄的DML(INSERT,UPDATE,DELETE)開銷,正確的索引可以讓性能提升100,1000倍以上,不合理的索引也可能會讓性能下降100倍,因此在一個表中創(chuàng)建什么樣的索引需要平衡各種業(yè)務(wù)需求。
索引常見問題:
索引有哪些種類?
常見的索引有B-TREE索引、位圖索引、全文索引,位圖索引一般用于數(shù)據(jù)倉庫應(yīng)用,全文索引由于使用較少,這里不深入介紹。B-TREE索引包括很多擴(kuò)展類型,如組合索引、反向索引、函數(shù)索引等等,以下是B-TREE索引的簡單介紹:
B-TREE索引也稱為平衡樹索引(Balance Tree),它是一種按字段排好序的樹形目錄結(jié)構(gòu),主要用于提升查詢性能和唯一約束支持。B-TREE索引的內(nèi)容包括根節(jié)點(diǎn)、分支節(jié)點(diǎn)、葉子節(jié)點(diǎn)。
葉子節(jié)點(diǎn)內(nèi)容:索引字段內(nèi)容+表記錄ROWID
根節(jié)點(diǎn),分支節(jié)點(diǎn)內(nèi)容:當(dāng)一個數(shù)據(jù)塊中不能放下所有索引字段數(shù)據(jù)時,就會形成樹形的根節(jié)點(diǎn)或分支節(jié)點(diǎn),根節(jié)點(diǎn)與分支節(jié)點(diǎn)保存了索引樹的順序及各層級間的引用關(guān)系。
一個普通的BTREE索引結(jié)構(gòu)示意圖如下所示:
1.2、只通過索引訪問數(shù)據(jù)
有些時候,我們只是訪問表中的幾個字段,并且字段內(nèi)容較少,我們可以為這幾個字段單獨(dú)建立一個組合索引,這樣就可以直接只通過訪問索引就能得到數(shù)據(jù),一般索引占用的磁盤空間比表小很多,所以這種方式可以大大減少磁盤IO開銷。
如:select id,name from company where type='2';
如果這個SQL經(jīng)常使用,我們可以在type,id,name上創(chuàng)建組合索引
create index my_comb_index on company(type,id,name);
有了這個組合索引后,SQL就可以直接通過my_comb_index索引返回數(shù)據(jù),不需要訪問company表。
還是拿字典舉例:有一個需求,需要查詢一本漢語字典中所有漢字的個數(shù),如果我們的字典沒有目錄索引,那我們只能從字典內(nèi)容里一個一個字計數(shù),最后返回結(jié)果。如果我們有一個拼音目錄,那就可以只訪問拼音目錄的漢字進(jìn)行計數(shù)。如果一本字典有1000頁,拼音目錄有20頁,那我們的數(shù)據(jù)訪問成本相當(dāng)于全表訪問的50分之一。
切記,性能優(yōu)化是無止境的,當(dāng)性能可以滿足需求時即可,不要過度優(yōu)化。在實(shí)際數(shù)據(jù)庫中我們不可能把每個SQL請求的字段都建在索引里,所以這種只通過索引訪問數(shù)據(jù)的方法一般只用于核心應(yīng)用,也就是那種對核心表訪問量最高且查詢字段數(shù)據(jù)量很少的查詢。
1.3、優(yōu)化SQL執(zhí)行計劃
SQL執(zhí)行計劃是關(guān)系型數(shù)據(jù)庫最核心的技術(shù)之一,它表示SQL執(zhí)行時的數(shù)據(jù)訪問算法。由于業(yè)務(wù)需求越來越復(fù)雜,表數(shù)據(jù)量也越來越大,程序員越來越懶惰,SQL也需要支持非常復(fù)雜的業(yè)務(wù)邏輯,但SQL的性能還需要提高,因此,優(yōu)秀的關(guān)系型數(shù)據(jù)庫除了需要支持復(fù)雜的SQL語法及更多函數(shù)外,還需要有一套優(yōu)秀的算法庫來提高SQL性能。
目前ORACLE有SQL執(zhí)行計劃的算法約300種,而且一直在增加,所以SQL執(zhí)行計劃是一個非常復(fù)雜的課題,一個普通DBA能掌握50種就很不錯了,就算是資深DBA也不可能把每個執(zhí)行計劃的算法描述清楚。雖然有這么多種算法,但并不表示我們無法優(yōu)化執(zhí)行計劃,因為我們常用的SQL執(zhí)行計劃算法也就十幾個,如果一個程序員能把這十幾個算法搞清楚,那就掌握了80%的SQL執(zhí)行計劃調(diào)優(yōu)知識。
由于篇幅的原因,SQL執(zhí)行計劃需要專題介紹,在這里就不多說了。
2、返回更少的數(shù)據(jù)
2.1、數(shù)據(jù)分頁處理
一般數(shù)據(jù)分頁方式有:
2.1.1、客戶端(應(yīng)用程序或瀏覽器)分頁
將數(shù)據(jù)從應(yīng)用服務(wù)器全部下載到本地應(yīng)用程序或瀏覽器,在應(yīng)用程序或瀏覽器內(nèi)部通過本地代碼進(jìn)行分頁處理
優(yōu)點(diǎn):編碼簡單,減少客戶端與應(yīng)用服務(wù)器網(wǎng)絡(luò)交互次數(shù)
缺點(diǎn):首次交互時間長,占用客戶端內(nèi)存
適應(yīng)場景:客戶端與應(yīng)用服務(wù)器網(wǎng)絡(luò)延時較大,但要求后續(xù)操作流暢,如手機(jī)GPRS,超遠(yuǎn)程訪問(跨國)等等。
2.1.2、應(yīng)用服務(wù)器分頁
將數(shù)據(jù)從數(shù)據(jù)庫服務(wù)器全部下載到應(yīng)用服務(wù)器,在應(yīng)用服務(wù)器內(nèi)部再進(jìn)行數(shù)據(jù)篩選。以下是一個應(yīng)用服務(wù)器端Java程序分頁的示例:
List list=executeQuery(“select * from employee order by id”);
Int count= list.size();
List subList= list.subList(10, 20);
優(yōu)點(diǎn):編碼簡單,只需要一次SQL交互,總數(shù)據(jù)與分頁數(shù)據(jù)差不多時性能較好。
缺點(diǎn):總數(shù)據(jù)量較多時性能較差。
適應(yīng)場景:數(shù)據(jù)庫系統(tǒng)不支持分頁處理,數(shù)據(jù)量較小并且可控。
2.1.3、數(shù)據(jù)庫SQL分頁
采用數(shù)據(jù)庫SQL分頁需要兩次SQL完成
一個SQL計算總數(shù)量
一個SQL返回分頁后的數(shù)據(jù)
優(yōu)點(diǎn):性能好
缺點(diǎn):編碼復(fù)雜,各種數(shù)據(jù)庫語法不同,需要兩次SQL交互。
oracle數(shù)據(jù)庫一般采用rownum來進(jìn)行分頁,常用分頁語法有如下兩種:
直接通過rownum分頁:
select * from (
select a.*,rownum rn from
(select * from product a where company_id=? order by status) a
where rownum<=20)
where rn>10;
數(shù)據(jù)訪問開銷=索引IO+索引全部記錄結(jié)果對應(yīng)的表數(shù)據(jù)IO
采用rowid分頁語法
優(yōu)化原理是通過純索引找出分頁記錄的ROWID,再通過ROWID回表返回數(shù)據(jù),要求內(nèi)層查詢和排序字段全在索引里。
create index myindex on product(company_id,status);
select b.* from (
select * from (
select a.*,rownum rn from
(select rowid rid,status from product a where company_id=? order by status) a
where rownum<=20)
where rn>10) a, product b
where a.rid=b.rowid;
數(shù)據(jù)訪問開銷=索引IO+索引分頁結(jié)果對應(yīng)的表數(shù)據(jù)IO
實(shí)例:
一個公司產(chǎn)品有1000條記錄,要分頁取其中20個產(chǎn)品,假設(shè)訪問公司索引需要50個IO,2條記錄需要1個表數(shù)據(jù)IO。
那么按第一種ROWNUM分頁寫法,需要550(50+1000/2)個IO,按第二種ROWID分頁寫法,只需要60個IO(50+20/2);
2.2、只返回需要的字段
通過去除不必要的返回字段可以提高性能,例:
調(diào)整前:select * from product where company_id=?;
調(diào)整后:select id,name from product where company_id=?;
優(yōu)點(diǎn):
1、減少數(shù)據(jù)在網(wǎng)絡(luò)上傳輸開銷
2、減少服務(wù)器數(shù)據(jù)處理開銷
3、減少客戶端內(nèi)存占用
4、字段變更時提前發(fā)現(xiàn)問題,減少程序BUG
5、如果訪問的所有字段剛好在一個索引里面,則可以使用純索引訪問提高性能。
缺點(diǎn):增加編碼工作量
由于會增加一些編碼工作量,所以一般需求通過開發(fā)規(guī)范來要求程序員這么做,否則等項目上線后再整改工作量更大。
如果你的查詢表中有大字段或內(nèi)容較多的字段,如備注信息、文件內(nèi)容等等,那在查詢表時一定要注意這方面的問題,否則可能會帶來嚴(yán)重的性能問題。如果表經(jīng)常要查詢并且請求大內(nèi)容字段的概率很低,我們可以采用分表處理,將一個大表分拆成兩個一對一的關(guān)系表,將不常用的大內(nèi)容字段放在一張單獨(dú)的表中。如一張存儲上傳文件的表:
T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE,FILE_CONTENT)
我們可以分拆成兩張一對一的關(guān)系表:
T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE)
T_FILECONTENT(ID, FILE_CONTENT)
通過這種分拆,可以大大提少T_FILE表的單條記錄及總大小,這樣在查詢T_FILE時性能會更好,當(dāng)需要查詢FILE_CONTENT字段內(nèi)容時再訪問T_FILECONTENT表。
3、減少交互次數(shù)
3.1、batch DML
數(shù)據(jù)庫訪問框架一般都提供了批量提交的接口,jdbc支持batch的提交處理方法,當(dāng)你一次性要往一個表中插入1000萬條數(shù)據(jù)時,如果采用普通的executeUpdate處理,那么和服務(wù)器交互次數(shù)為1000萬次,按每秒鐘可以向數(shù)據(jù)庫服務(wù)器提交10000次估算,要完成所有工作需要1000秒。如果采用批量提交模式,1000條提交一次,那么和服務(wù)器交互次數(shù)為1萬次,交互次數(shù)大大減少。采用batch操作一般不會減少很多數(shù)據(jù)庫服務(wù)器的物理IO,但是會大大減少客戶端與服務(wù)端的交互次數(shù),從而減少了多次發(fā)起的網(wǎng)絡(luò)延時開銷,同時也會降低數(shù)據(jù)庫的CPU開銷。
3.2 緩存概念
通過redis等內(nèi)存工具將數(shù)據(jù)庫緩存到內(nèi)存中
3.3 全文搜索 es
可以將數(shù)據(jù)進(jìn)行導(dǎo)入es中進(jìn)行緩存,然后查詢只是在es中查詢,可以減少對數(shù)據(jù)庫的交互
?這個是很早之前總結(jié)的,一直在有道云筆記上,希望大家拍磚.
?
轉(zhuǎn)載于:https://www.cnblogs.com/xiufengchen/p/10350369.html
總結(jié)
- 上一篇: java additem 错,Java错
- 下一篇: 37wan《武易》全新系统机密放送