MySQL數(shù)據(jù)庫性能優(yōu)化介紹
為什么做優(yōu)化??
因為數(shù)據(jù)量太多了,項目部署上線再到用戶使用,每天數(shù)據(jù)增長幾十萬條,給服務(wù)器帶來非常大的負(fù)擔(dān),互聯(lián)網(wǎng)一直追求高性能,可是隨著業(yè)務(wù)規(guī)模變大,用戶數(shù)量變多,服務(wù)器的性能越來越差,因此我們不得不對數(shù)據(jù)庫有更高要求。
從哪些方面入手??
第一,是查詢的速度,我們期望數(shù)據(jù)量到達(dá)TB級別仍然能夠?qū)崿F(xiàn)百萬級別查詢速度。
第二、是并發(fā)量,我們對它的要求能夠同時處理幾千甚至上萬的并發(fā)訪問,還要配合Redis、MQ等。??
第三,高可用,隨著業(yè)務(wù)規(guī)模不斷變大,我們要隨時準(zhǔn)備對服務(wù)器進(jìn)行擴(kuò)展,可能由原來幾十臺服務(wù)器擴(kuò)展到上百臺甚至上千臺服務(wù)器,所以我們要搭載MySQL集群。
第四,事務(wù)的安全性,當(dāng)業(yè)務(wù)出現(xiàn)高并發(fā)訪問,怎么保證讀寫一致性???保證事務(wù)的安全性???? 參考多線程的思路。。?
解決方案是什么???
第一個思考的是應(yīng)該用什么樣的存儲引擎,因為存儲引擎決定著它的性能,好比你是用汽車、飛機(jī)還是坦克, 每個引擎都有它特殊的作用。 業(yè)務(wù)上常用的是兩種,INNODB和MYISAM。
?要怎樣選擇???
當(dāng)我們對業(yè)務(wù)沒有過多的讀寫要求,以查詢?yōu)橹鳎褂肕yISAM,當(dāng)我們對事務(wù)完整性要求較高,并發(fā)要求高,增刪頻繁,經(jīng)常進(jìn)行讀寫操作,使用INNODB更好。
第二個我們要給加快查詢速度, 所以要給表特殊字段添加索引,索引的原理是改變數(shù)據(jù)的存儲結(jié)構(gòu),這里分為兩種:第一是BTree,第二是B+Tree。 我們業(yè)務(wù)上一般使用的是B+Tree,BTree有一個特點,是根節(jié)點和葉子節(jié)點都會存放數(shù)據(jù),這會造成比如查詢最底層葉子節(jié)點,會一層一層讀根節(jié)點的數(shù)據(jù),會增加磁盤I/O次數(shù),無形當(dāng)中又會增加數(shù)據(jù)庫的壓力。 所以要用B+Tree
第三實現(xiàn)高可用方案, 這里我們會為數(shù)據(jù)庫服務(wù)搭載主從結(jié)構(gòu)集群,緩解讀和寫的壓力?
第四是安全問題,這里可以參考線程的安全問題,比如怎么解決高并發(fā)訪問??如何能保證事務(wù)的完整性??? 像RocketMQ也涉及事務(wù)消息,? 如何避免這類問題, 我們可以上鎖。 以下是鎖的分類。
SQL優(yōu)化
1、查詢盡量避免全表掃描,首先考慮在where、order by字段上添加索引
2、避免在where字段上使用NULL值,所以在設(shè)計表時盡量使用NOT NULL約束,有些數(shù)據(jù)會默認(rèn)為NULL,可以設(shè)置默認(rèn)值為0或者-1
3、避免在where子句中使用!=或<>操作符,Mysql只對<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE使用索引
4、避免在where中使用OR來連接條件,否則可能導(dǎo)致引擎放棄索引來執(zhí)行全表掃描,可以使用UNION進(jìn)行合并查詢
? ? ? select id from t where num = 30 union select id from t where num = 40;
5、盡量避免在where子句中進(jìn)行函數(shù)或者表達(dá)式操作
6、最好不要使用select * from t,用具體的字段列表代替"*",不要返回用不到的任何字段
7、in 和 not in 也要慎用,否則會導(dǎo)致全表掃描,如
select id from t where num IN(1,2,3)如果是連續(xù)的值建議使用between and,select id from t where between 1 and 3;
8、select id from t where col like %a%;模糊查詢左側(cè)有%會導(dǎo)致全表檢索,如果需要全文檢索可以使用全文搜索引擎比如es,slor
9、limit offset rows關(guān)于分頁查詢,盡量保證不要出現(xiàn)大的offset,比如limit 10000,10相當(dāng)于對已查詢出來的行數(shù)棄掉前10000行后再取10行,完全可以加一些條件過濾一下(完成篩選),而不應(yīng)該使用limit跳過已查詢到的數(shù)據(jù)。這是一個==offset做無用功==的問題。對應(yīng)實際工程中,要避免出現(xiàn)大頁碼的情況,盡量引導(dǎo)用戶做條件過濾
總結(jié)
到此這篇關(guān)于MySQL數(shù)據(jù)庫性能優(yōu)化介紹的文章就介紹到這了,更多相關(guān)MySQL性能優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL使用binlog日志做數(shù)據(jù)恢復(fù)的實現(xiàn)
這篇文章主要介紹了MySQL使用binlog日志做數(shù)據(jù)恢復(fù)的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03在Qt中操作MySQL數(shù)據(jù)庫的實戰(zhàn)指南
QT連接Mysql數(shù)據(jù)庫的步驟相對繁瑣,但是也是一個不錯的學(xué)習(xí)經(jīng)歷,下面這篇文章主要給大家介紹了關(guān)于在Qt中操作MySQL數(shù)據(jù)庫的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04詳解MySQL中concat函數(shù)的用法(連接字符串)
本篇文章主要介紹了MySQL中concat函數(shù)的用法(連接字符串),在命令行模式下進(jìn)行測試。具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-12-12Mysql報錯1292:Incorrect datetime value for 
本文主要介紹了Mysql報錯1292:Incorrect datetime value for column create_time at row 1 解決方案,1292 是指插入或更新操作時,日期或時間值不正確引起的錯誤,下面就來介紹一下2024-02-02