99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

MySQL中比較常用的優(yōu)化手段

Linux愛(ài)好者 ? 來(lái)源:非科班的科班 ? 作者:非科班的科班 ? 2021-03-10 10:05 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、準(zhǔn)備表數(shù)據(jù)

咱們建一張用戶表,表中的字段有用戶ID、用戶名、地址、記錄創(chuàng)建時(shí)間,如圖所示

e5d10ad6-8103-11eb-8b86-12bb97331649.png

OK,接下來(lái)準(zhǔn)備寫(xiě)一個(gè)存儲(chǔ)過(guò)程插入一百萬(wàn)條數(shù)據(jù)

CREATE TABLE `t_user` (

`id` int NOT NULL,

`user_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,

`address` varchar(255) DEFAULT NULL,

`create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DELIMITER ;;

CREATE PROCEDURE user_insert()

BEGIN

DECLARE i INT DEFAULT 0;

WHILE i《1000000

DO

INSERT INTO t_user(id, user_name, address, create_time) VALUES (i, CONCAT(‘mayun’,i), ‘浙江杭州’, now());

SET i=i+1;

END WHILE ;

commit;

END;;

CALL user_insert();

插入完后咱們看看數(shù)據(jù)條數(shù)

e5e1fcce-8103-11eb-8b86-12bb97331649.png

二、優(yōu)化方式

1.分頁(yè)查詢優(yōu)化

OK,咱們看下分頁(yè)limit到一定值時(shí)的耗時(shí)是多少

limit 1000時(shí)

e6052988-8103-11eb-8b86-12bb97331649.png

limit 10000時(shí)

e635f64e-8103-11eb-8b86-12bb97331649.png

limit 100000時(shí)

e6539154-8103-11eb-8b86-12bb97331649.png

limit 1000000時(shí)

e66ca4be-8103-11eb-8b86-12bb97331649.png

可以看到limit值越大,耗時(shí)越長(zhǎng),這還只是一百萬(wàn)數(shù)據(jù),要是千萬(wàn)級(jí)、億級(jí)呢?

OK不廢話,咱們馬上進(jìn)行分頁(yè)優(yōu)化

子查詢優(yōu)化

e6887176-8103-11eb-8b86-12bb97331649.png

-

可以看到比起之前 limit 1000000時(shí)的0.218s 效率提高了很多

使用JOIN分頁(yè)

e6a5d810-8103-11eb-8b86-12bb97331649.png

-

可以看到比起之前 limit 1000000時(shí)的0.218s 效率也同樣提高了很多

使用前一次查詢的最大ID

e6c1ed98-8103-11eb-8b86-12bb97331649.png

可以看到這種方法效率最高,但依賴于需要知道最大ID,這種適合點(diǎn)擊下一頁(yè)查詢(類似于滾動(dòng)加載數(shù)據(jù))的場(chǎng)景

通過(guò)偽列對(duì)ID進(jìn)行分頁(yè)

e6e273b0-8103-11eb-8b86-12bb97331649.png

然后可以開(kāi)啟多個(gè)線程去進(jìn)行最高效率查詢語(yǔ)句的批量查詢操作 0~10000,10001-20000.。.. 這樣子的話可以快速把全量數(shù)據(jù)查詢出來(lái)同步至緩存中。

分頁(yè)優(yōu)化總結(jié): 使用前一次查詢的最大ID進(jìn)行查詢優(yōu)化是效率最高的方法,但這種方法只適用于下一頁(yè)點(diǎn)擊的這種操作,對(duì)于同步全量數(shù)據(jù)來(lái)說(shuō)建議的方式使用偽列對(duì)ID進(jìn)行分頁(yè),然后開(kāi)啟多個(gè)線程同時(shí)查詢,把全量數(shù)據(jù)加載到緩存,以后面試官問(wèn)你如何 快速獲取海量數(shù)據(jù)并加載到緩存 你該知道怎么回答了吧。

2.普通索引優(yōu)化

先來(lái)看沒(méi)索引優(yōu)化的情況下的查詢效率

e70f4142-8103-11eb-8b86-12bb97331649.png

可以看到這時(shí)沒(méi)用索引的情況,用了0.305S接下來(lái)看看加了索引后的結(jié)果

普通索引優(yōu)化

e74f297e-8103-11eb-8b86-12bb97331649.png

e75e053e-8103-11eb-8b86-12bb97331649.png

只需要0.024S,我們可以EXPLAIN看下

e7792cb0-8103-11eb-8b86-12bb97331649.png

可以看到使用了普通索引后查詢效率明顯增加

3.復(fù)合索引優(yōu)化

復(fù)合索引什么時(shí)候用?為什么要用?圍繞著這兩問(wèn)題,咱們先來(lái)說(shuō)說(shuō)復(fù)合索引什么時(shí)候用

單表中查詢、條件語(yǔ)句中具有較多個(gè)字段

使用索引會(huì)影響寫(xiě)的效率,需要研究建立最優(yōu)秀的索引

我們這里建議一個(gè)復(fù)合索引

e7d3740e-8103-11eb-8b86-12bb97331649.png

MySQL建立復(fù)合索引時(shí)實(shí)際建立了(user_name)、(user_name,address)、(user_name,address,create_time)三個(gè)索引,我們都知道每多一個(gè)索引,都會(huì)增加寫(xiě)操作的開(kāi)銷和磁盤(pán)空間的開(kāi)銷,對(duì)于海量數(shù)據(jù)的表,這可是不小的開(kāi)銷,所以你會(huì)發(fā)現(xiàn)我們?cè)谶@里使用復(fù)合索引一個(gè)頂三個(gè),又能減少寫(xiě)操作的開(kāi)銷和磁盤(pán)空間的開(kāi)銷。

當(dāng)我們select user_name,address,create_time from t_user where user_name=xx and address = xxx時(shí),MySQL可以直接通過(guò)遍歷索引取得數(shù)據(jù),無(wú)需回表,這減少了很多的隨機(jī)IO操作。所以,在真正的實(shí)際應(yīng)用中,這就是覆蓋索引,是復(fù)合索引中主要的提升性能的優(yōu)化手段之一。

4.SQL查詢優(yōu)化

避免使用OR,看看例子

e7ef15a6-8103-11eb-8b86-12bb97331649.png

可以看到這條語(yǔ)句沒(méi)有使用到索引,是因?yàn)楫?dāng)or左右查詢字段只有一個(gè)是索引,該索引失效,只有當(dāng)or左右查詢字段均為索引時(shí),才會(huì)生效。

不要使用like ‘%xx’ %在左邊時(shí)索引失效

e80376c2-8103-11eb-8b86-12bb97331649.png

3. 使用復(fù)合索引時(shí)沒(méi)有遵循最左匹配原則

e819abb8-8103-11eb-8b86-12bb97331649.png

ref:這個(gè)連接類型只有在查詢使用了不是惟一或主鍵的鍵或者是這些類型的部分(比如,利用最左邊前綴)時(shí)發(fā)生。沒(méi)有值說(shuō)明沒(méi)有利用最左前綴原則

再來(lái)看個(gè)使用了最左前綴的例子

e82b80c2-8103-11eb-8b86-12bb97331649.png

4. 不要讓數(shù)據(jù)類型出現(xiàn)隱式轉(zhuǎn)化

可以看以下兩個(gè)例子

e83ba20e-8103-11eb-8b86-12bb97331649.png

e85b1d1e-8103-11eb-8b86-12bb97331649.png

5. 不要在索引字段上使用not,《》,!=,一樣會(huì)導(dǎo)致索引失效

e87bff5c-8103-11eb-8b86-12bb97331649.png

e89bdb74-8103-11eb-8b86-12bb97331649.png

e8bdb366-8103-11eb-8b86-12bb97331649.png

6. 分解關(guān)聯(lián)查詢 例如這條語(yǔ)句

e8cffd5a-8103-11eb-8b86-12bb97331649.png

可以分解成

e8ebb50e-8103-11eb-8b86-12bb97331649.png

7.小表驅(qū)動(dòng)大表 即小的數(shù)據(jù)集驅(qū)動(dòng)大的數(shù)據(jù)集。如:以t_user,t_order兩表為例,兩表通過(guò) t_user的id字段進(jìn)行關(guān)聯(lián)。

當(dāng) t_order表的數(shù)據(jù)集小于t_user表時(shí),用 in 優(yōu)化 exist,使用 in,兩表執(zhí)行順序是先查 t_order 表,再查t_user表

select * from t_user where id in (select user_id from t_order)

當(dāng) t_user 表的數(shù)據(jù)集小于 t_order 表時(shí),用 exist 優(yōu)化 in,使用 exists,兩表執(zhí)行順序是先查 t_user 表,再查 t_order 表

select * from t_user where exists (select 1 from B where t_order.user_id= t_user.id)

5.事務(wù)優(yōu)化

首先了解下事務(wù)的隔離級(jí)別,數(shù)據(jù)庫(kù)共定義了四種隔離級(jí)別:

Serializable:可避免臟讀、不可重復(fù)讀、虛讀情況的發(fā)生。(串行化)

Repeatable read:可避免臟讀、不可重復(fù)讀情況的發(fā)生。(可重復(fù)讀)

Read committed:可避免臟讀情況發(fā)生(讀已提交)。

Read uncommitted:最低級(jí)別,以上情況均無(wú)法保證。(讀未提交)

可以通過(guò) set transaction isolation level 設(shè)置事務(wù)隔離級(jí)別來(lái)提高性能

6.數(shù)據(jù)庫(kù)性能優(yōu)化

開(kāi)啟查詢緩存

在解析一個(gè)查詢語(yǔ)句前,如果查詢緩存是打開(kāi)的,那么MySQL會(huì)檢查這個(gè)查詢語(yǔ)句是否命中查詢緩存中的數(shù)據(jù)。如果當(dāng)前查詢恰好命中查詢緩存,在檢查一次用戶權(quán)限后直接返回緩存中的結(jié)果。這種情況下,查詢不會(huì)被解析,也不會(huì)生成執(zhí)行計(jì)劃,更不會(huì)執(zhí)行。MySQL將緩存存放在一個(gè)引用表(不要理解成table,可以認(rèn)為是類似于HashMap的數(shù)據(jù)結(jié)構(gòu)),通過(guò)一個(gè)哈希值索引,這個(gè)哈希值通過(guò)查詢本身、當(dāng)前要查詢的數(shù)據(jù)庫(kù)、客戶端協(xié)議版本號(hào)等一些可能影響結(jié)果的信息計(jì)算得來(lái)。所以兩個(gè)查詢?cè)谌魏巫址系牟煌ɡ纾嚎崭?、注釋),都?huì)導(dǎo)致緩存不會(huì)命中。

如果查詢中包含任何用戶自定義函數(shù)、存儲(chǔ)函數(shù)、用戶變量、臨時(shí)表、mysql庫(kù)中的系統(tǒng)表,其查詢結(jié)果都不會(huì)被緩存。比如函數(shù)NOW()或者CURRENT_DATE()會(huì)因?yàn)椴煌牟樵儠r(shí)間,返回不同的查詢結(jié)果,再比如包含CURRENT_USER或者CONNECION_ID()的查詢語(yǔ)句會(huì)因?yàn)椴煌挠脩舳祷夭煌慕Y(jié)果,將這樣的查詢結(jié)果緩存起來(lái)沒(méi)有任何的意義。

既然是緩存,就會(huì)失效,那查詢緩存何時(shí)失效呢?MySQL的查詢緩存系統(tǒng)會(huì)跟蹤查詢中涉及的每個(gè)表,如果這些表(數(shù)據(jù)或結(jié)構(gòu))發(fā)生變化,那么和這張表相關(guān)的所有緩存數(shù)據(jù)都將失效。正因?yàn)槿绱?,在任何的?xiě)操作時(shí),MySQL必須將對(duì)應(yīng)表的所有緩存都設(shè)置為失效。如果查詢緩存非常大或者碎片很多,這個(gè)操作就可能帶來(lái)很大的系統(tǒng)消耗,甚至導(dǎo)致系統(tǒng)僵死一會(huì)兒。而且查詢緩存對(duì)系統(tǒng)的額外消耗也不僅僅在寫(xiě)操作,讀操作也不例外:

任何的查詢語(yǔ)句在開(kāi)始之前都必須經(jīng)過(guò)檢查,即使這條SQL語(yǔ)句永遠(yuǎn)不會(huì)命中緩存

如果查詢結(jié)果可以被緩存,那么執(zhí)行完成后,會(huì)將結(jié)果存入緩存,也會(huì)帶來(lái)額外的系統(tǒng)消耗

基于此,我們要知道并不是什么情況下查詢緩存都會(huì)提高系統(tǒng)性能,緩存和失效都會(huì)帶來(lái)額外消耗,只有當(dāng)緩存帶來(lái)的資源節(jié)約大于其本身消耗的資源時(shí),才會(huì)給系統(tǒng)帶來(lái)性能提升。但要如何評(píng)估打開(kāi)緩存是否能夠帶來(lái)性能提升是一件非常困難的事情,也不在本文討論的范疇內(nèi)。如果系統(tǒng)確實(shí)存在一些性能問(wèn)題,可以嘗試打開(kāi)查詢緩存,并在數(shù)據(jù)庫(kù)設(shè)計(jì)上做一些優(yōu)化,比如:

批量插入代替循環(huán)單條插入 。 合理控制緩存空間大小,一般來(lái)說(shuō)其大小設(shè)置為幾十兆比較合適 。 可以通過(guò)SQL\_CACHE和SQL\_NO\_CACHE來(lái)控制某個(gè)查詢語(yǔ)句是否需要進(jìn)行緩存 最后的忠告是不要輕易打開(kāi)查詢緩存,特別是寫(xiě)密集型應(yīng)用。如果你實(shí)在是忍不住,可以將query\_cache\_type設(shè)置為DEMAND,這時(shí)只有加入SQL\_CACHE的查詢才會(huì)走緩存,其他查詢則不會(huì),這樣可以非常自由地控制哪些查詢需要被緩存。 當(dāng)然查詢緩存系統(tǒng)本身是非常復(fù)雜的,這里討論的也只是很小的一部分,其他更深入的話題,比如:緩存是如何使用內(nèi)存的?如何控制內(nèi)存的碎片化?事務(wù)對(duì)查詢緩存有何影響等等,讀者可以自行閱讀相關(guān)資料,這里權(quán)當(dāng)拋磚引玉吧。 **語(yǔ)法解析和預(yù)處理**

MySQL通過(guò)關(guān)鍵字將SQL語(yǔ)句進(jìn)行解析,并生成一顆對(duì)應(yīng)的解析樹(shù)。這個(gè)過(guò)程解析器主要通過(guò)語(yǔ)法規(guī)則來(lái)驗(yàn)證和解析。比如SQL中是否使用了錯(cuò)誤的關(guān)鍵字或者關(guān)鍵字的順序是否正確等等。預(yù)處理則會(huì)根據(jù)MySQL規(guī)則進(jìn)一步檢查解析樹(shù)是否合法。比如檢查要查詢的數(shù)據(jù)表和數(shù)據(jù)列是否存在等等。

7.系統(tǒng)內(nèi)核參數(shù)優(yōu)化

```bash

#基礎(chǔ)配置

datadir=/data/datafile

socket=/var/lib/mysql/mysql.sock

log-error=/data/log/mysqld.log

pid-file=/var/run/mysqld/mysqld.pid

character_set_server=utf8

#允許任意IP訪問(wèn)

bind-address = 0.0.0.0

#是否支持符號(hào)鏈接,即數(shù)據(jù)庫(kù)或表可以存儲(chǔ)在my.cnf中指定datadir之外的分區(qū)或目錄,為0不開(kāi)啟

#symbolic-links=0

#支持大小寫(xiě)

lower_case_table_names=1

#二進(jìn)制配置

server-id = 1

log-bin = /data/log/mysql-bin.log

log-bin-index =/data/log/binlog.index

log_bin_trust_function_creators=1

expire_logs_days=7

#sql_mode定義了mysql應(yīng)該支持的sql語(yǔ)法,數(shù)據(jù)校驗(yàn)等

#mysql5.0以上版本支持三種sql_mode模式:ANSI、TRADITIONAL和STRICT_TRANS_TABLES。

#ANSI模式:寬松模式,對(duì)插入數(shù)據(jù)進(jìn)行校驗(yàn),如果不符合定義類型或長(zhǎng)度,對(duì)數(shù)據(jù)類型調(diào)整或截?cái)啾4?,?bào)warning警告。

#TRADITIONAL模式:嚴(yán)格模式,當(dāng)向mysql數(shù)據(jù)庫(kù)插入數(shù)據(jù)時(shí),進(jìn)行數(shù)據(jù)的嚴(yán)格校驗(yàn),保證錯(cuò)誤數(shù)據(jù)不能插入,報(bào)error錯(cuò)誤。用于事物時(shí),會(huì)進(jìn)行事物的回滾。

#STRICT_TRANS_TABLES模式:嚴(yán)格模式,進(jìn)行數(shù)據(jù)的嚴(yán)格校驗(yàn),錯(cuò)誤數(shù)據(jù)不能插入,報(bào)error錯(cuò)誤。

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

#InnoDB存儲(chǔ)數(shù)據(jù)字典、內(nèi)部數(shù)據(jù)結(jié)構(gòu)的緩沖池,16MB已經(jīng)足夠大了。

innodb_additional_mem_pool_size = 16M

#InnoDB用于緩存數(shù)據(jù)、索引、鎖、插入緩沖、數(shù)據(jù)字典等

#如果是專用的DB服務(wù)器,且以InnoDB引擎為主的場(chǎng)景,通??稍O(shè)置物理內(nèi)存的60%

#如果是非專用DB服務(wù)器,可以先嘗試設(shè)置成內(nèi)存的1/4

innodb_buffer_pool_size = 4G

#InnoDB的log buffer,通常設(shè)置為 64MB 就足夠了

innodb_log_buffer_size = 64M

#InnoDB redo log大小,通常設(shè)置256MB 就足夠了

innodb_log_file_size = 256M

#InnoDB redo log文件組,通常設(shè)置為 2 就足夠了

innodb_log_files_in_group = 2

#共享表空間:某一個(gè)數(shù)據(jù)庫(kù)的所有的表數(shù)據(jù),索引文件全部放在一個(gè)文件中,默認(rèn)這個(gè)共享表空間的文件路徑在data目錄下。默認(rèn)的文件名為:ibdata1 初始化為10M。

#獨(dú)占表空間:每一個(gè)表都將會(huì)生成以獨(dú)立的文件方式來(lái)進(jìn)行存儲(chǔ),每一個(gè)表都有一個(gè).frm表描述文件,還有一個(gè).ibd文件。其中這個(gè)文件包括了單獨(dú)一個(gè)表的數(shù)據(jù)內(nèi)容以及索引內(nèi)容,默認(rèn)情況下它的存儲(chǔ)位置也是在表的位置之中。

#設(shè)置參數(shù)為1啟用InnoDB的獨(dú)立表空間模式,便于管理

innodb_file_per_table = 1

#InnoDB共享表空間初始化大小,默認(rèn)是 10MB,改成 1GB,并且自動(dòng)擴(kuò)展

innodb_data_file_path = ibdata1autoextend

#設(shè)置臨時(shí)表空間最大4G

innodb_temp_data_file_path=ibtmp1autoextend4096M

#啟用InnoDB的status file,便于管理員查看以及監(jiān)控

innodb_status_file = 1

#當(dāng)設(shè)置為0,該模式速度最快,但不太安全,mysqld進(jìn)程的崩潰會(huì)導(dǎo)致上一秒鐘所有事務(wù)數(shù)據(jù)的丟失。

#當(dāng)設(shè)置為1,該模式是最安全的,但也是最慢的一種方式。在mysqld 服務(wù)崩潰或者服務(wù)器主機(jī)crash的情況下,binary log 只有可能丟失最多一個(gè)語(yǔ)句或者一個(gè)事務(wù)。

#當(dāng)設(shè)置為2,該模式速度較快,也比0安全,只有在操作系統(tǒng)崩潰或者系統(tǒng)斷電的情況下,上一秒鐘所有事務(wù)數(shù)據(jù)才可能丟失。

innodb_flush_log_at_trx_commit = 1

#設(shè)置事務(wù)隔離級(jí)別為 READ-COMMITED,提高事務(wù)效率,通常都滿足事務(wù)一致性要求

#transaction_isolation = READ-COMMITTED

#max_connections:針對(duì)所有的賬號(hào)所有的客戶端并行連接到MYSQL服務(wù)的最大并行連接數(shù)。簡(jiǎn)單說(shuō)是指MYSQL服務(wù)能夠同時(shí)接受的最大并行連接數(shù)。

#max_user_connections : 針對(duì)某一個(gè)賬號(hào)的所有客戶端并行連接到MYSQL服務(wù)的最大并行連接數(shù)。簡(jiǎn)單說(shuō)是指同一個(gè)賬號(hào)能夠同時(shí)連接到mysql服務(wù)的最大連接數(shù)。設(shè)置為0表示不限制。

#max_connect_errors:針對(duì)某一個(gè)IP主機(jī)連接中斷與mysql服務(wù)連接的次數(shù),如果超過(guò)這個(gè)值,這個(gè)IP主機(jī)將會(huì)阻止從這個(gè)IP主機(jī)發(fā)送出去的連接請(qǐng)求。遇到這種情況,需執(zhí)行flush hosts。

#執(zhí)行flush host或者 mysqladmin flush-hosts,其目的是為了清空host cache里的信息??蛇m當(dāng)加大,防止頻繁連接錯(cuò)誤后,前端host被mysql拒絕掉

#在 show global 里有個(gè)系統(tǒng)狀態(tài)Max_used_connections,它是指從這次mysql服務(wù)啟動(dòng)到現(xiàn)在,同一時(shí)刻并行連接數(shù)的最大值。它不是指當(dāng)前的連接情況,而是一個(gè)比較值。如果在過(guò)去某一個(gè)時(shí)刻,MYSQL服務(wù)同時(shí)有10

00個(gè)請(qǐng)求連接過(guò)來(lái),而之后再也沒(méi)有出現(xiàn)這么大的并發(fā)請(qǐng)求時(shí),則Max_used_connections=1000.請(qǐng)注意與show variables 里的max_user_connections的區(qū)別。#Max_used_connections / max_connections * 100% ≈ 85%

max_connections=600

max_connect_errors=1000

max_user_connections=400

#設(shè)置臨時(shí)表最大值,這是每次連接都會(huì)分配,不宜設(shè)置過(guò)大 max_heap_table_size 和 tmp_table_size 要設(shè)置一樣大

max_heap_table_size = 100M

tmp_table_size = 100M

#每個(gè)連接都會(huì)分配的一些排序、連接等緩沖,一般設(shè)置為 2MB 就足夠了

sort_buffer_size = 2M

join_buffer_size = 2M

read_buffer_size = 2M

read_rnd_buffer_size = 2M

#建議關(guān)閉query cache,有些時(shí)候?qū)π阅芊炊且环N損害

query_cache_size = 0

#如果是以InnoDB引擎為主的DB,專用于MyISAM引擎的 key_buffer_size 可以設(shè)置較小,8MB 已足夠

#如果是以MyISAM引擎為主,可設(shè)置較大,但不能超過(guò)4G

key_buffer_size = 8M

#設(shè)置連接超時(shí)閥值,如果前端程序采用短連接,建議縮短這2個(gè)值,如果前端程序采用長(zhǎng)連接,可直接注釋掉這兩個(gè)選項(xiàng),是用默認(rèn)配置(8小時(shí))

#interactive_timeout = 120

#wait_timeout = 120

#InnoDB使用后臺(tái)線程處理數(shù)據(jù)頁(yè)上讀寫(xiě)I/0請(qǐng)求的數(shù)量,允許值的范圍是1-64

#假設(shè)CPU是2顆4核的,且數(shù)據(jù)庫(kù)讀操作比寫(xiě)操作多,可設(shè)置

#innodb_read_io_threads=5

#innodb_write_io_threads=3

#通過(guò)show engine innodb status的FILE I/O選項(xiàng)可查看到線程分配

#設(shè)置慢查詢閥值,單位為秒

long_query_time = 120

slow_query_log=1 #開(kāi)啟mysql慢sql的日志

log_output=table,F(xiàn)ile #日志輸出會(huì)寫(xiě)表,也會(huì)寫(xiě)日志文件,為了便于程序去統(tǒng)計(jì),所以最好寫(xiě)表

slow_query_log_file=/data/log/slow.log

##針對(duì)log_queries_not_using_indexes開(kāi)啟后,記錄慢sql的頻次、每分鐘記錄的條數(shù)

#log_throttle_queries_not_using_indexes = 5

##作為從庫(kù)時(shí)生效,從庫(kù)復(fù)制中如何有慢sql也將被記錄

#log_slow_slave_statements = 1

##檢查未使用到索引的sql

#log_queries_not_using_indexes = 1

#快速預(yù)熱緩沖池

innodb_buffer_pool_dump_at_shutdown=1

innodb_buffer_pool_load_at_startup=1

#打印deadlock日志

innodb_print_all_deadlocks=1

這些參數(shù)可按照自己的實(shí)際服務(wù)器以及數(shù)據(jù)庫(kù)的大小進(jìn)行適當(dāng)調(diào)整,主要起參考作用

8.表字段優(yōu)化

很多系統(tǒng)一開(kāi)始并沒(méi)有考慮表字段拆分的問(wèn)題,因?yàn)椴鸱謺?huì)帶來(lái)邏輯、部署、運(yùn)維的各種復(fù)雜度,一般以整型值為主的表在千萬(wàn)級(jí)以下,字符串為主的表在五百萬(wàn)以下,而事實(shí)上很多時(shí)候MySQL單表的性能依然有不少優(yōu)化空間,甚至能正常支撐千萬(wàn)級(jí)以上的數(shù)據(jù)量:

下面直接看下如何去優(yōu)化字段

盡量使用TINYINT、SMALLINT、MEDIUM_INT作為整數(shù)類型而非INT,如果非負(fù)則加上UNSIGNED

單表不要有太多字段,建議在15以內(nèi)

盡量使用TIMESTAMP而非DATETIME

使用枚舉或整數(shù)代替字符串類型

VARCHAR的長(zhǎng)度只分配真正需要的空間

避免使用NULL字段,很難查詢優(yōu)化且占用額外索引空間

用整型來(lái)存IP

9.分布式場(chǎng)景下常用優(yōu)化手段

升級(jí)硬件

Scale up,這個(gè)不多說(shuō)了,根據(jù)MySQL是CPU密集型還是I/O密集型,通過(guò)提升CPU和內(nèi)存、使用SSD,都能顯著提升MySQL性能

讀寫(xiě)分離

也是目前常用的優(yōu)化,從庫(kù)讀主庫(kù)寫(xiě),一般不要采用雙主或多主引入很多復(fù)雜性,盡量采用文中的其他方案來(lái)提高性能。同時(shí)目前很多拆分的解決方案同時(shí)也兼顧考慮了讀寫(xiě)分離

使用緩存

緩存可以發(fā)生在這些層次:

MySQL內(nèi)部:在系統(tǒng)內(nèi)核參數(shù)優(yōu)化介紹了相關(guān)設(shè)置

數(shù)據(jù)訪問(wèn)層:比如MyBatis針對(duì)SQL語(yǔ)句做緩存,而Hibernate可以精確到單個(gè)記錄,這里緩存的對(duì)象主要是持久化對(duì)象Persistence Object

應(yīng)用服務(wù)層:這里可以通過(guò)編程手段對(duì)緩存做到更精準(zhǔn)的控制和更多的實(shí)現(xiàn)策略,這里緩存的對(duì)象是數(shù)據(jù)傳輸對(duì)象Data Transfer Object

Web層:針對(duì)web頁(yè)面做緩存

瀏覽器客戶端:用戶端的緩存

可以根據(jù)實(shí)際情況在一個(gè)層次或多個(gè)層次結(jié)合加入緩存。這里重點(diǎn)介紹下服務(wù)層的緩存實(shí)現(xiàn),目前主要有兩種方式:

直寫(xiě)式(Write Through):在數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)后,同時(shí)更新緩存,維持?jǐn)?shù)據(jù)庫(kù)與緩存的一致性。這也是當(dāng)前大多數(shù)應(yīng)用緩存框架如Spring Cache的工作方式。這種實(shí)現(xiàn)非常簡(jiǎn)單,同步好,但效率一般。

回寫(xiě)式(Write Back):當(dāng)有數(shù)據(jù)要寫(xiě)入數(shù)據(jù)庫(kù)時(shí),只會(huì)更新緩存,然后異步批量的將緩存數(shù)據(jù)同步到數(shù)據(jù)庫(kù)上。這種實(shí)現(xiàn)比較復(fù)雜,需要較多的應(yīng)用邏輯,同時(shí)可能會(huì)產(chǎn)生數(shù)據(jù)庫(kù)與緩存的不同步,但效率非常高。

水平拆分。

總結(jié)

其實(shí)MySQL的優(yōu)化還有很多,有興趣的可以讀讀MySQL高性能優(yōu)化的書(shū),但以上這些是在我們實(shí)際生產(chǎn)環(huán)境中比較常用的優(yōu)化手段,掌握這些,不是我吹,能吊打一般的面試官了。

原文標(biāo)題:MySQL 海量數(shù)據(jù)優(yōu)化(理論+實(shí)戰(zhàn)) 吊打面試官

文章出處:【微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    860

    瀏覽量

    27925

原文標(biāo)題:MySQL 海量數(shù)據(jù)優(yōu)化(理論+實(shí)戰(zhàn)) 吊打面試官

文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    MySQL數(shù)據(jù)備份與恢復(fù)策略

    數(shù)據(jù)是企業(yè)的核心資產(chǎn),MySQL作為主流的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),其數(shù)據(jù)的安全性和可靠性至關(guān)重要。本文將深入探討MySQL的數(shù)據(jù)備份策略、常用備份工具以及數(shù)據(jù)恢復(fù)的最佳實(shí)踐,幫助運(yùn)維工程師構(gòu)建完善的數(shù)據(jù)保護(hù)體系。
    的頭像 發(fā)表于 07-14 11:11 ?119次閱讀

    企業(yè)級(jí)MySQL數(shù)據(jù)庫(kù)管理指南

    在當(dāng)今數(shù)字化時(shí)代,MySQL作為全球最受歡迎的開(kāi)源關(guān)系型數(shù)據(jù)庫(kù),承載著企業(yè)核心業(yè)務(wù)數(shù)據(jù)的存儲(chǔ)與處理。作為數(shù)據(jù)庫(kù)管理員(DBA),掌握MySQL的企業(yè)級(jí)部署、優(yōu)化、維護(hù)技能至關(guān)重要。本文將從實(shí)戰(zhàn)角度出發(fā),系統(tǒng)闡述
    的頭像 發(fā)表于 07-09 09:50 ?122次閱讀

    使用插件將Excel連接到MySQL/MariaDB

    使用插件將 Excel 連接到 MySQL/MariaDB 適用于 MySQL 的 Devart Excel 插件允許您將 Microsoft Excel 連接到 MySQL 或 MariaDB
    的頭像 發(fā)表于 01-20 12:38 ?614次閱讀
    使用插件將Excel連接到<b class='flag-5'>MySQL</b>/MariaDB

    MySQL數(shù)據(jù)庫(kù)的安裝

    MySQL數(shù)據(jù)庫(kù)的安裝 【一】各種數(shù)據(jù)庫(kù)的端口 MySQL :3306 Redis :6379 MongoDB :27017 Django :8000 flask :5000 【二】MySQL 介紹
    的頭像 發(fā)表于 01-14 11:25 ?562次閱讀
    <b class='flag-5'>MySQL</b>數(shù)據(jù)庫(kù)的安裝

    淺談SQL優(yōu)化小技巧

    作者:京東零售 王軍 回顧:MySQL的執(zhí)行過(guò)程回顧 MySQL的執(zhí)行過(guò)程,幫助 介紹 如何進(jìn)行sql優(yōu)化。 (1)客戶端發(fā)送一條查詢語(yǔ)句到服務(wù)器; (2)服務(wù)器先查詢緩存,如果命中緩存,則立即返回
    的頭像 發(fā)表于 12-25 09:59 ?856次閱讀

    MySQL還能跟上PostgreSQL的步伐嗎

    Percona 的老板 Peter Zaitsev最近發(fā)表一篇博客,討論了MySQL是否還能跟上PostgreSQL的腳步。Percona 作為MySQL 生態(tài)扛旗者,Percona 開(kāi)發(fā)了知名
    的頭像 發(fā)表于 11-18 10:16 ?563次閱讀
    <b class='flag-5'>MySQL</b>還能跟上PostgreSQL的步伐嗎

    詳解MySQL多實(shí)例部署

    詳解MySQL多實(shí)例部署
    的頭像 發(fā)表于 11-11 11:10 ?638次閱讀

    MySQL編碼機(jī)制原理

    前言 一位讀者在本地部署 MySQL 測(cè)試環(huán)境時(shí)碰到一個(gè)問(wèn)題,我覺(jué)得挺有代表性的,所以寫(xiě)篇文章介紹一下,看完相信你會(huì)對(duì) MySQL 的編碼機(jī)制有最本質(zhì)的了解,本文的目錄結(jié)構(gòu)如下 讀者問(wèn)題簡(jiǎn)介
    的頭像 發(fā)表于 11-09 11:01 ?581次閱讀

    適用于MySQL的dbForge架構(gòu)比較

    dbForge Schema Compare for MySQL 是一種工具,用于輕松有效地比較和部署 MySQL 數(shù)據(jù)庫(kù)結(jié)構(gòu)和腳本文件夾差異。該工具提供了 MySQL 數(shù)據(jù)庫(kù)架構(gòu)中所
    的頭像 發(fā)表于 10-28 09:41 ?570次閱讀
    適用于<b class='flag-5'>MySQL</b>的dbForge架構(gòu)<b class='flag-5'>比較</b>

    MySQL性能優(yōu)化淺析及線上案例

    手段則會(huì)對(duì)用戶的使用體驗(yàn)造成影響,嚴(yán)重的則會(huì)直接導(dǎo)致訂單、金額直接受損,因而就需要時(shí)刻關(guān)注數(shù)據(jù)庫(kù)的性能問(wèn)題。 2、 性能優(yōu)化的幾個(gè)常見(jiàn)措施 數(shù)據(jù)庫(kù)性能優(yōu)化的常見(jiàn)手段有很多,比如添加索引
    的頭像 發(fā)表于 10-22 15:17 ?1018次閱讀
    <b class='flag-5'>MySQL</b>性能<b class='flag-5'>優(yōu)化</b>淺析及線上案例

    請(qǐng)問(wèn)常用的高速比較器有哪些?

    常用的高速比較器有哪些?
    發(fā)表于 09-03 07:23

    單片機(jī)中比較器的重要參數(shù)

    比較器(Comparator,簡(jiǎn)寫(xiě)COMP)是MCU的一個(gè)常用外設(shè),它用于比較兩路模擬信號(hào)的電壓大小,輸出的是一個(gè)數(shù)字信號(hào),用于指示哪路輸入信號(hào)更大。
    的頭像 發(fā)表于 08-29 10:19 ?1417次閱讀
    單片機(jī)<b class='flag-5'>中比較</b>器的重要參數(shù)

    優(yōu)化比較器輸入端上的電阻分壓器

    電子發(fā)燒友網(wǎng)站提供《優(yōu)化比較器輸入端上的電阻分壓器.pdf》資料免費(fèi)下載
    發(fā)表于 08-26 14:53 ?4次下載
    <b class='flag-5'>優(yōu)化</b><b class='flag-5'>比較</b>器輸入端上的電阻分壓器

    MySQL知識(shí)點(diǎn)匯總

    大家好,這部分被稱為DQL部分,是每個(gè)學(xué)習(xí)MySQL必須要學(xué)會(huì)的部分,下面就讓我來(lái)介紹MySQL中的其他部分。
    的頭像 發(fā)表于 08-05 15:27 ?654次閱讀
    <b class='flag-5'>MySQL</b>知識(shí)點(diǎn)匯總

    華納云:如何修改MySQL的默認(rèn)端口

    MySQL是世界上最流行的開(kāi)源關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)之一。在某些情況下,由于安全性、網(wǎng)絡(luò)策略或端口沖突的原因,數(shù)據(jù)庫(kù)管理員可能需要更改MySQL服務(wù)的默認(rèn)監(jiān)聽(tīng)端口。本文將指導(dǎo)您如何在不同的操作系統(tǒng)上
    的頭像 發(fā)表于 07-22 14:56 ?538次閱讀
    華納云:如何修改<b class='flag-5'>MySQL</b>的默認(rèn)端口