日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

mysql优化三

發(fā)布時(shí)間:2023/12/10 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql优化三 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

相對(duì)高并發(fā)一樣,速度都是優(yōu)化出來(lái)的,在高并發(fā)處理的時(shí)候,通常采用的是redis緩存,全文搜索引擎,數(shù)據(jù)庫(kù)本身優(yōu)化,sql優(yōu)化,磁盤(pán)優(yōu)化

看如下圖:

所以可以得出的思想就是:

這個(gè)優(yōu)化法則歸納為5個(gè)層次:
1、 減少數(shù)據(jù)訪問(wèn)(減少磁盤(pán)訪問(wèn))
2、 返回更少數(shù)據(jù)(減少網(wǎng)絡(luò)傳輸或磁盤(pán)訪問(wèn))
3、 減少交互次數(shù)(減少網(wǎng)絡(luò)傳輸)
4、 減少服務(wù)器CPU開(kāi)銷(xiāo)(減少CPU及內(nèi)存開(kāi)銷(xiāo))
5、 利用更多資源(增加資源)

1、減少數(shù)據(jù)訪問(wèn)
  1.1、創(chuàng)建并使用正確的索引
數(shù)據(jù)庫(kù)索引的原理非常簡(jiǎn)單,但在復(fù)雜的表中真正能正確使用索引的人很少,即使是專(zhuān)業(yè)的DBA也不一定能完全做到最優(yōu)。
索引會(huì)大大增加表記錄的DML(INSERT,UPDATE,DELETE)開(kāi)銷(xiāo),正確的索引可以讓性能提升100,1000倍以上,不合理的索引也可能會(huì)讓性能下降100倍,因此在一個(gè)表中創(chuàng)建什么樣的索引需要平衡各種業(yè)務(wù)需求。
索引常見(jiàn)問(wèn)題:
索引有哪些種類(lèi)?
  常見(jiàn)的索引有B-TREE索引、位圖索引、全文索引,位圖索引一般用于數(shù)據(jù)倉(cāng)庫(kù)應(yīng)用,全文索引由于使用較少,這里不深入介紹。B-TREE索引包括很多擴(kuò)展類(lèi)型,如組合索引、反向索引、函數(shù)索引等等,以下是B-TREE索引的簡(jiǎn)單介紹:
B-TREE索引也稱為平衡樹(shù)索引(Balance Tree),它是一種按字段排好序的樹(shù)形目錄結(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)一個(gè)數(shù)據(jù)塊中不能放下所有索引字段數(shù)據(jù)時(shí),就會(huì)形成樹(shù)形的根節(jié)點(diǎn)或分支節(jié)點(diǎn),根節(jié)點(diǎn)與分支節(jié)點(diǎn)保存了索引樹(shù)的順序及各層級(jí)間的引用關(guān)系。
一個(gè)普通的BTREE索引結(jié)構(gòu)示意圖如下所示:


1.2、只通過(guò)索引訪問(wèn)數(shù)據(jù)
  有些時(shí)候,我們只是訪問(wèn)表中的幾個(gè)字段,并且字段內(nèi)容較少,我們可以為這幾個(gè)字段單獨(dú)建立一個(gè)組合索引,這樣就可以直接只通過(guò)訪問(wèn)索引就能得到數(shù)據(jù),一般索引占用的磁盤(pán)空間比表小很多,所以這種方式可以大大減少磁盤(pán)IO開(kāi)銷(xiāo)。
如:select id,name from company where type='2';
如果這個(gè)SQL經(jīng)常使用,我們可以在type,id,name上創(chuàng)建組合索引
create index my_comb_index on company(type,id,name);
  有了這個(gè)組合索引后,SQL就可以直接通過(guò)my_comb_index索引返回?cái)?shù)據(jù),不需要訪問(wèn)company表。
還是拿字典舉例:有一個(gè)需求,需要查詢一本漢語(yǔ)字典中所有漢字的個(gè)數(shù),如果我們的字典沒(méi)有目錄索引,那我們只能從字典內(nèi)容里一個(gè)一個(gè)字計(jì)數(shù),最后返回結(jié)果。如果我們有一個(gè)拼音目錄,那就可以只訪問(wèn)拼音目錄的漢字進(jìn)行計(jì)數(shù)。如果一本字典有1000頁(yè),拼音目錄有20頁(yè),那我們的數(shù)據(jù)訪問(wèn)成本相當(dāng)于全表訪問(wèn)的50分之一。
切記,性能優(yōu)化是無(wú)止境的,當(dāng)性能可以滿足需求時(shí)即可,不要過(guò)度優(yōu)化。在實(shí)際數(shù)據(jù)庫(kù)中我們不可能把每個(gè)SQL請(qǐng)求的字段都建在索引里,所以這種只通過(guò)索引訪問(wèn)數(shù)據(jù)的方法一般只用于核心應(yīng)用,也就是那種對(duì)核心表訪問(wèn)量最高且查詢字段數(shù)據(jù)量很少的查詢。

1.3、優(yōu)化SQL執(zhí)行計(jì)劃
  SQL執(zhí)行計(jì)劃是關(guān)系型數(shù)據(jù)庫(kù)最核心的技術(shù)之一,它表示SQL執(zhí)行時(shí)的數(shù)據(jù)訪問(wèn)算法。由于業(yè)務(wù)需求越來(lái)越復(fù)雜,表數(shù)據(jù)量也越來(lái)越大,程序員越來(lái)越懶惰,SQL也需要支持非常復(fù)雜的業(yè)務(wù)邏輯,但SQL的性能還需要提高,因此,優(yōu)秀的關(guān)系型數(shù)據(jù)庫(kù)除了需要支持復(fù)雜的SQL語(yǔ)法及更多函數(shù)外,還需要有一套優(yōu)秀的算法庫(kù)來(lái)提高SQL性能。
目前ORACLE有SQL執(zhí)行計(jì)劃的算法約300種,而且一直在增加,所以SQL執(zhí)行計(jì)劃是一個(gè)非常復(fù)雜的課題,一個(gè)普通DBA能掌握50種就很不錯(cuò)了,就算是資深DBA也不可能把每個(gè)執(zhí)行計(jì)劃的算法描述清楚。雖然有這么多種算法,但并不表示我們無(wú)法優(yōu)化執(zhí)行計(jì)劃,因?yàn)槲覀兂S玫腟QL執(zhí)行計(jì)劃算法也就十幾個(gè),如果一個(gè)程序員能把這十幾個(gè)算法搞清楚,那就掌握了80%的SQL執(zhí)行計(jì)劃調(diào)優(yōu)知識(shí)。
由于篇幅的原因,SQL執(zhí)行計(jì)劃需要專(zhuān)題介紹,在這里就不多說(shuō)了。

2、返回更少的數(shù)據(jù)
2.1、數(shù)據(jù)分頁(yè)處理
  一般數(shù)據(jù)分頁(yè)方式有:
  2.1.1、客戶端(應(yīng)用程序或?yàn)g覽器)分頁(yè)
  將數(shù)據(jù)從應(yīng)用服務(wù)器全部下載到本地應(yīng)用程序或?yàn)g覽器,在應(yīng)用程序或?yàn)g覽器內(nèi)部通過(guò)本地代碼進(jìn)行分頁(yè)處理
  優(yōu)點(diǎn):編碼簡(jiǎn)單,減少客戶端與應(yīng)用服務(wù)器網(wǎng)絡(luò)交互次數(shù)
  缺點(diǎn):首次交互時(shí)間長(zhǎng),占用客戶端內(nèi)存
  適應(yīng)場(chǎng)景:客戶端與應(yīng)用服務(wù)器網(wǎng)絡(luò)延時(shí)較大,但要求后續(xù)操作流暢,如手機(jī)GPRS,超遠(yuǎn)程訪問(wèn)(跨國(guó))等等。
  2.1.2、應(yīng)用服務(wù)器分頁(yè)
  將數(shù)據(jù)從數(shù)據(jù)庫(kù)服務(wù)器全部下載到應(yīng)用服務(wù)器,在應(yīng)用服務(wù)器內(nèi)部再進(jìn)行數(shù)據(jù)篩選。以下是一個(gè)應(yīng)用服務(wù)器端Java程序分頁(yè)的示例:
  List list=executeQuery(“select * from employee order by id”);
  Int count= list.size();
  List subList= list.subList(10, 20);

  優(yōu)點(diǎn):編碼簡(jiǎn)單,只需要一次SQL交互,總數(shù)據(jù)與分頁(yè)數(shù)據(jù)差不多時(shí)性能較好。
  缺點(diǎn):總數(shù)據(jù)量較多時(shí)性能較差。
  適應(yīng)場(chǎng)景:數(shù)據(jù)庫(kù)系統(tǒng)不支持分頁(yè)處理,數(shù)據(jù)量較小并且可控。

2.1.3、數(shù)據(jù)庫(kù)SQL分頁(yè)
  采用數(shù)據(jù)庫(kù)SQL分頁(yè)需要兩次SQL完成
  一個(gè)SQL計(jì)算總數(shù)量
  一個(gè)SQL返回分頁(yè)后的數(shù)據(jù)
優(yōu)點(diǎn):性能好
缺點(diǎn):編碼復(fù)雜,各種數(shù)據(jù)庫(kù)語(yǔ)法不同,需要兩次SQL交互。

oracle數(shù)據(jù)庫(kù)一般采用rownum來(lái)進(jìn)行分頁(yè),常用分頁(yè)語(yǔ)法有如下兩種:

直接通過(guò)rownum分頁(yè):
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ù)訪問(wèn)開(kāi)銷(xiāo)=索引IO+索引全部記錄結(jié)果對(duì)應(yīng)的表數(shù)據(jù)IO

采用rowid分頁(yè)語(yǔ)法
優(yōu)化原理是通過(guò)純索引找出分頁(yè)記錄的ROWID,再通過(guò)ROWID回表返回?cái)?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ù)訪問(wèn)開(kāi)銷(xiāo)=索引IO+索引分頁(yè)結(jié)果對(duì)應(yīng)的表數(shù)據(jù)IO

實(shí)例:
一個(gè)公司產(chǎn)品有1000條記錄,要分頁(yè)取其中20個(gè)產(chǎn)品,假設(shè)訪問(wèn)公司索引需要50個(gè)IO,2條記錄需要1個(gè)表數(shù)據(jù)IO。
那么按第一種ROWNUM分頁(yè)寫(xiě)法,需要550(50+1000/2)個(gè)IO,按第二種ROWID分頁(yè)寫(xiě)法,只需要60個(gè)IO(50+20/2);

2.2、只返回需要的字段
通過(guò)去除不必要的返回字段可以提高性能,例:
調(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ò)上傳輸開(kāi)銷(xiāo)
2、減少服務(wù)器數(shù)據(jù)處理開(kāi)銷(xiāo)
3、減少客戶端內(nèi)存占用
4、字段變更時(shí)提前發(fā)現(xiàn)問(wèn)題,減少程序BUG
5、如果訪問(wèn)的所有字段剛好在一個(gè)索引里面,則可以使用純索引訪問(wèn)提高性能。
缺點(diǎn):增加編碼工作量
由于會(huì)增加一些編碼工作量,所以一般需求通過(guò)開(kāi)發(fā)規(guī)范來(lái)要求程序員這么做,否則等項(xiàng)目上線后再整改工作量更大。
如果你的查詢表中有大字段或內(nèi)容較多的字段,如備注信息、文件內(nèi)容等等,那在查詢表時(shí)一定要注意這方面的問(wèn)題,否則可能會(huì)帶來(lái)嚴(yán)重的性能問(wèn)題。如果表經(jīng)常要查詢并且請(qǐng)求大內(nèi)容字段的概率很低,我們可以采用分表處理,將一個(gè)大表分拆成兩個(gè)一對(duì)一的關(guān)系表,將不常用的大內(nèi)容字段放在一張單獨(dú)的表中。如一張存儲(chǔ)上傳文件的表:
T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE,FILE_CONTENT)
我們可以分拆成兩張一對(duì)一的關(guān)系表:
T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE)
T_FILECONTENT(ID, FILE_CONTENT)
通過(guò)這種分拆,可以大大提少T_FILE表的單條記錄及總大小,這樣在查詢T_FILE時(shí)性能會(huì)更好,當(dāng)需要查詢FILE_CONTENT字段內(nèi)容時(shí)再訪問(wèn)T_FILECONTENT表。

3、減少交互次數(shù)
3.1、batch DML
  數(shù)據(jù)庫(kù)訪問(wèn)框架一般都提供了批量提交的接口,jdbc支持batch的提交處理方法,當(dāng)你一次性要往一個(gè)表中插入1000萬(wàn)條數(shù)據(jù)時(shí),如果采用普通的executeUpdate處理,那么和服務(wù)器交互次數(shù)為1000萬(wàn)次,按每秒鐘可以向數(shù)據(jù)庫(kù)服務(wù)器提交10000次估算,要完成所有工作需要1000秒。如果采用批量提交模式,1000條提交一次,那么和服務(wù)器交互次數(shù)為1萬(wàn)次,交互次數(shù)大大減少。采用batch操作一般不會(huì)減少很多數(shù)據(jù)庫(kù)服務(wù)器的物理IO,但是會(huì)大大減少客戶端與服務(wù)端的交互次數(shù),從而減少了多次發(fā)起的網(wǎng)絡(luò)延時(shí)開(kāi)銷(xiāo),同時(shí)也會(huì)降低數(shù)據(jù)庫(kù)的CPU開(kāi)銷(xiāo)。
3.2 緩存概念

  通過(guò)redis等內(nèi)存工具將數(shù)據(jù)庫(kù)緩存到內(nèi)存中

3.3 全文搜索 es

  可以將數(shù)據(jù)進(jìn)行導(dǎo)入es中進(jìn)行緩存,然后查詢只是在es中查詢,可以減少對(duì)數(shù)據(jù)庫(kù)的交互

?這個(gè)是很早之前總結(jié)的,一直在有道云筆記上,希望大家拍磚.

?

轉(zhuǎn)載于:https://www.cnblogs.com/xiufengchen/p/10350369.html

總結(jié)

以上是生活随笔為你收集整理的mysql优化三的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。