Mysql知識(shí)點(diǎn)總結(jié)

一弦讽、存儲(chǔ)引擎

1侣颂、SQL語(yǔ)句執(zhí)行流程
MySQL大體上可分為Server層和存儲(chǔ)引擎層兩部分胯甩。
Server層:

  • 連接器:TCP握手后服務(wù)器來(lái)驗(yàn)證登陸用戶身份啃沪,A用戶創(chuàng)建連接后粘拾,管理員對(duì)A用戶權(quán)限修改了也不會(huì)影響到已經(jīng)創(chuàng)建的鏈接權(quán)限,必須重新登陸创千。
  • 查詢緩存:查詢后的結(jié)果存儲(chǔ)位置缰雇,MySQL8.0版本以后已經(jīng)取消,因?yàn)椴樵兙彺媸l繁追驴,得不償失械哟。
  • 分析器:根據(jù)語(yǔ)法規(guī)則,判斷你輸入的這個(gè)SQL語(yǔ)句是否滿足MySQL語(yǔ)法殿雪。
  • 優(yōu)化器:多種執(zhí)行策略可實(shí)現(xiàn)目標(biāo)暇咆,系統(tǒng)自動(dòng)選擇最優(yōu)進(jìn)行執(zhí)行。
  • 執(zhí)行器:判斷是否有權(quán)限,將最終任務(wù)提交到存儲(chǔ)引擎爸业。

存儲(chǔ)引擎:

  • Innodb(默認(rèn)):innodb里面完整數(shù)據(jù)都在主鍵索引的葉子節(jié)點(diǎn)上面其骄。主鍵索引:存儲(chǔ)索引和數(shù)據(jù);輔助索引:存儲(chǔ)索引和主鍵值
    • (1)支持事務(wù)(redo log和undo log)扯旷;
    • (2)行級(jí)鎖年栓;支持外鍵薄霜;
    • (3)支持崩潰后的安全恢復(fù)(bin log)某抓;
    • (4)支持MVCC;
    • (5)不保存表的具體行數(shù)惰瓜,執(zhí)行select count(*) from table時(shí)需要全表掃描否副;
  • MyISAM:有兩個(gè)存儲(chǔ)文件,data和index分開崎坊;主鍵索引和輔助索引的方式相同备禀,需要再index文件上面拿到數(shù)據(jù)的磁盤地址
    • (1)不支持事務(wù);
    • (2)默認(rèn)表級(jí)鎖;不支持外鍵奈揍;
    • (3)不支持崩潰后的安全恢復(fù)曲尸;
    • (4)支持MVCC;
    • (5)MyISAM用一個(gè)變量保存了整個(gè)表的行數(shù)男翰,執(zhí)行select count(*) from table時(shí)只需要讀出該變量即可另患,速度很快;
  • Memory:也叫 HEAP(堆內(nèi)存)蛾绎,使用存在內(nèi)存中的內(nèi)容來(lái)創(chuàng)建表昆箕。
    • 不允許使用BLOB或TEXT字段
    • 只能使用比較運(yùn)算符=,<租冠,>鹏倘,=>,= <
    • HEAP表不支持AUTO_INCREMENT
    • 索引不可為NULL
2顽爹、一張表里面有ID自增主鍵纤泵,當(dāng)insert了17條記錄之后,刪除了第15,16,17條記錄镜粤,再把mysql重啟捏题,再insert一條記錄,這條記錄的ID是18還是15 繁仁?

一般情況下涉馅,我們創(chuàng)建的表的類型是InnoDB归园,如果新增一條記錄(不重啟mysql的情況下)黄虱,這條記錄的id是18;但是如果重啟(文中提到的)MySQL的話庸诱,這條記錄的ID是15捻浦。因?yàn)镮nnoDB表只把自增主鍵的最大ID記錄到內(nèi)存中晤揣,所以重啟數(shù)據(jù)庫(kù)或者對(duì)表OPTIMIZE操作,都會(huì)使最大ID丟失朱灿。
但是昧识,如果我們使用表的類型是MylSAM,那么這條記錄的ID就是18盗扒。因?yàn)镸ylSAM表會(huì)把自增主鍵的最大ID記錄到數(shù)據(jù)文件里面跪楞,重啟MYSQL后,自增主鍵的最大ID也不會(huì)丟失侣灶。

二甸祭、索引

1、索引為什么使用B+樹而不是B樹褥影?
  • IO次數(shù)少:B+樹的中間結(jié)點(diǎn)只存放索引池户,數(shù)據(jù)都存在葉結(jié)點(diǎn)中,因此中間結(jié)點(diǎn)可以存更多的數(shù)據(jù)凡怎,讓索引樹更加矮胖校焦;
  • 范圍查詢效率更高:B樹需要中序遍歷整個(gè)樹,只B+樹需要遍歷葉結(jié)點(diǎn)中的鏈表统倒;
  • 查詢效率更加穩(wěn)定:每次查詢都需要從根結(jié)點(diǎn)到葉結(jié)點(diǎn)寨典,路徑長(zhǎng)度相同,所以每次查詢的效率都差不多房匆;
2凝赛、索引的幾個(gè)概念:
  • 聚簇索引:B+樹的非葉子節(jié)點(diǎn)只存儲(chǔ)索引,而葉子節(jié)點(diǎn)存儲(chǔ)索引和數(shù)據(jù)坛缕,這種索引和數(shù)據(jù)在一起存儲(chǔ)的索引方式叫做聚簇索引墓猎。一張表只能有一個(gè)聚簇索引。
    (1)如果表定義了主鍵赚楚,則之間就是聚集索引毙沾;
    (2)如果表沒有定義主鍵,則第一個(gè)非空唯一索引是聚集索引宠页;
    (3)如果沒有這樣的非空索引左胞,InnoDB會(huì)創(chuàng)建一個(gè)隱藏的row_id作為聚集索引;
  • 非聚簇索引:非聚簇索引(二級(jí)索引)保存的是主鍵值举户,這一點(diǎn)和myisam保存的是數(shù)據(jù)地址是不同的烤宙。
  • 覆蓋索引:覆蓋索引指的是在一次查詢中,如果一個(gè)索引包含或者說(shuō)覆蓋所有需要查詢的字段的值俭嘁,我們就稱之為覆蓋索引躺枕,而不再需要回表查詢。
  • 回表:先通過(guò)普通索引的值定位聚簇索引值,再通過(guò)聚簇索引的值定位行數(shù)據(jù)拐云,去取普通索引中未能提供的數(shù)據(jù)罢猪,即為回表。
    explain select * from user where age=1; //查詢的name無(wú)法從索引數(shù)據(jù)獲取 (回表)
    explain select id,age from user where age=1; //可以直接從索引獲炔娲瘛(覆蓋索引)
  • 聯(lián)合索引:相對(duì)單列索引膳帕,組合索引是用多個(gè)列組合構(gòu)建的索引。
  • 最左匹配原則:對(duì)多個(gè)字段同時(shí)建立的組合索引(有順序薇缅,ABC危彩,ACB是完全不同的兩種聯(lián)合索引) 以聯(lián)合索引(a,b,c)為例,建立這樣的索引相當(dāng)于建立了索引a泳桦、ab恬砂、abc三個(gè)索引。另外組合索引實(shí)際還是一個(gè)索引蓬痒,并非真的創(chuàng)建了多個(gè)索引泻骤,只是產(chǎn)生的效果等價(jià)于產(chǎn)生多個(gè)索引。
3梧奢、索引的缺點(diǎn):
  • (1)創(chuàng)建跟維護(hù)索引都需要消耗時(shí)間
  • (2)創(chuàng)建索引時(shí)狱掂,需要對(duì)表加鎖,在鎖表的同時(shí)亲轨,可能會(huì)影響到其他的數(shù)據(jù)操作
  • (3)索引文件會(huì)占用磁盤空間
  • (4)當(dāng)對(duì)表中的數(shù)據(jù)進(jìn)行CRUD的時(shí)趋惨,也會(huì)觸發(fā)索引的維護(hù),而維護(hù)索引需要時(shí)間惦蚊,可能會(huì)降低數(shù)據(jù)操作性能
4器虾、索引設(shè)計(jì)的原則:
  • (1)頻繁增刪改的列不要建立索引
  • (2)有大量重復(fù)的列不要建立索引
  • (3)數(shù)據(jù)量小的表不要建立索引
5、索引的失效場(chǎng)景:
  • (1)模糊搜索:左模糊或全模糊都會(huì)導(dǎo)致索引失效蹦锋,比如'%a'和'%a%'兆沙。但是右模糊是可以利用索引的,比如'a%' 莉掂。
  • (2)隱式類型轉(zhuǎn)換:比如select * from t where name = xxx , name是字符串類型葛圃,但是沒有加引號(hào),所以是由MySQL隱式轉(zhuǎn)換的憎妙,所以會(huì)讓索引失效
  • (3)當(dāng)語(yǔ)句中帶有or的時(shí)候:比如select * from t where name=‘sw’ or age=14
  • (4)不符合聯(lián)合索引的最左前綴匹配:(A,B,C)的聯(lián)合索引库正,你只where了C或B或只有B,C
  • (5)如果mysql估計(jì)使用全表掃描要比使用索引快,則不使用索引。例如
    ① 某些范圍查詢 select * from table_name where key>1 and key<90
    ② 或者數(shù)據(jù)量極少的表
6厘唾、InnoDB引擎的行鎖是通過(guò)加在什么上實(shí)現(xiàn)的褥符?

答:基于索引;

7抚垃、使用like 'a%' 喷楣、like'%a'趟大、like'%a%'查詢時(shí)是否會(huì)使用索引

答:'a%'會(huì),其他兩個(gè)不會(huì)抡蛙;

8、為什么用自增列作為主鍵魂迄?

各條數(shù)據(jù)記錄按主鍵順序存放于主索引的葉子節(jié)點(diǎn)上(大小為一個(gè)內(nèi)存頁(yè)或磁盤頁(yè))粗截,每當(dāng)有一條新的記錄插入時(shí),MySQL會(huì)根據(jù)其主鍵將其插入適當(dāng)?shù)墓?jié)點(diǎn)和位置捣炬,如果頁(yè)面達(dá)到裝載因子(InnoDB默認(rèn)為15/16)熊昌,則開辟一個(gè)新的頁(yè)(節(jié)點(diǎn))。
如果表使用自增主鍵湿酸,那么每次插入新的記錄婿屹,記錄就會(huì)順序添加到當(dāng)前索引節(jié)點(diǎn)的后續(xù)位置,當(dāng)一頁(yè)寫滿推溃,就會(huì)自動(dòng)開辟一個(gè)新的頁(yè)昂利。
如果使用非自增主鍵,由于每次插入主鍵的值近似于隨機(jī)铁坎,因此每次新紀(jì)錄都要被插到現(xiàn)有索引頁(yè)得中間某個(gè)位置蜂奸。此時(shí)MySQL不得不為了將新記錄插到合適位置而移動(dòng)數(shù)據(jù),甚至目標(biāo)頁(yè)面可能已經(jīng)被回寫到磁盤上而從緩存中清掉硬萍,此時(shí)又要從磁盤上讀回來(lái)扩所,這增加了很多開銷。同時(shí)頻繁的移動(dòng)朴乖、分頁(yè)操作造成了大量的碎片祖屏,得到了不夠緊湊的索引結(jié)構(gòu),后續(xù)不得不通過(guò)OPTIMIZE TABLE來(lái)重建表并優(yōu)化填充頁(yè)面买羞。

三袁勺、事務(wù)

1、說(shuō)一下事務(wù)的基本特性和隔離級(jí)別畜普?

基本特性:ACID(原子性魁兼、一致性焕妙、隔離性寄啼、持久性)

  • 原子性:原子性指的是一個(gè)事務(wù)中的操作要么全部成功,要么全部失敗蠢挡。
  • 一致性:一致性指的是數(shù)據(jù)庫(kù)總是從一個(gè)一致性的狀態(tài)轉(zhuǎn)換到另外一個(gè)一致性的狀態(tài)儒鹿。比如A轉(zhuǎn)賬給B100塊錢化撕,假設(shè)中間sql執(zhí)行過(guò)程中系統(tǒng)崩潰A也不會(huì)損失100塊,因?yàn)槭聞?wù)沒有提交约炎,修改也就不會(huì)保存到數(shù)據(jù)庫(kù)植阴。
  • 隔離性:隔離性指的是一個(gè)事務(wù)的修改在最終提交前蟹瘾,對(duì)其他事務(wù)是不可見的。
  • 持久性:持久性指的是一旦事務(wù)提交掠手,所做的修改就會(huì)永久保存到數(shù)據(jù)庫(kù)中憾朴。

隔離級(jí)別:而隔離性有4個(gè)隔離級(jí)別,分別是:

  • 讀未提交:read uncommit 喷鸽,可能會(huì)讀到其他事務(wù)未提交的數(shù)據(jù)众雷,也叫做臟讀。
  • 讀已提交:read commit 做祝,兩次讀取結(jié)果不一致砾省,叫做不可重復(fù)讀。(不可重復(fù)讀現(xiàn)象指的是混槐,在一個(gè)事務(wù)內(nèi)编兄,連續(xù)兩次查詢同一條數(shù)據(jù),查到的結(jié)果前后不一樣)
  • 可重復(fù)讀:repeatable read 声登,這是mysql的默認(rèn)級(jí)別狠鸳,就是每次讀取結(jié)果都一樣,但是有可能產(chǎn)生幻讀悯嗓。
  • 串行化:serializable 碰煌,一般是不會(huì)使用的,他會(huì)給每一行讀取的數(shù)據(jù)加鎖绅作,會(huì)導(dǎo)致大量超時(shí)和鎖競(jìng)爭(zhēng)的問題芦圾。
2、那ACID靠什么保證的呢俄认?
  • 原子性由undo log日志保證个少,它記錄了需要回滾的日志信息,事務(wù)回滾時(shí)撤銷已經(jīng)執(zhí)行成功的sql
  • 一致性一般由代碼層面來(lái)保證
  • 隔離性由MVCC來(lái)保證
  • 持久性由內(nèi)存+redo log來(lái)保證眯杏,mysql修改數(shù)據(jù)同時(shí)在內(nèi)存和redo log記錄這次操作夜焦,事務(wù)提交的時(shí)候通過(guò)redo log刷盤,宕機(jī)的時(shí)候可以從redo log恢復(fù)
3岂贩、那你說(shuō)說(shuō)什么是幻讀茫经?

幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)時(shí),另一個(gè)事務(wù)又在該范圍內(nèi)插入了新行萎津,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時(shí)卸伞,會(huì)發(fā)現(xiàn)有新的幻影行。InnoDB存儲(chǔ)引擎通過(guò)多版本并發(fā)控制(MVCC)機(jī)制解決了該問題锉屈。注:其實(shí)多版本只是解決不可重復(fù)讀問題荤傲,而加上間隙鎖(也就是這里所謂的并發(fā)控制)才解決了幻讀問題。

4颈渊、什么是MVCC?

MVCC叫做多版本并發(fā)控制遂黍,實(shí)際上就是保存了數(shù)據(jù)在某個(gè)時(shí)間節(jié)點(diǎn)的快照终佛。我們每行數(shù)實(shí)際上隱藏了兩列,創(chuàng)建時(shí)間版本號(hào)雾家,過(guò)期(刪除)時(shí)間版本號(hào)铃彰,每開始一個(gè)新的事務(wù),版本號(hào)都會(huì)自動(dòng)遞增芯咧。

在MVCC并發(fā)控制中牙捉,讀操作可以分成兩類:快照讀 (snapshot read)與當(dāng)前讀 (current read)』5常快照讀鹃共,讀取的是記錄的可見版本 (有可能是歷史版本)鬼佣,不用加鎖驶拱。當(dāng)前讀,讀取的是記錄的最新版本晶衷,并且蓝纲,當(dāng)前讀返回的記錄,都會(huì)加上鎖晌纫,保證其他事務(wù)不會(huì)再并發(fā)修改這條記錄税迷。

  • 快照讀:簡(jiǎn)單的select操作,屬于快照讀锹漱,不加鎖箭养。
select * from table where ?
  • 當(dāng)前讀:特殊的讀操作,插入/更新/刪除操作哥牍,屬于當(dāng)前讀毕泌,需要加鎖。除了第一條語(yǔ)句嗅辣,對(duì)讀取記錄加S鎖 (共享鎖)外撼泛,其他的操作,都加的是X鎖 (排它鎖)
select * from table where ? lock in share mode
select * from table where ? for update
insert into table values (…)
update table set ? where ?
delete from table where ?
5澡谭、InnoDB的行鎖模式及加鎖方法愿题?
  • 共享鎖(s):又稱讀鎖。允許一個(gè)事務(wù)去讀一行蛙奖,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖潘酗。若事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上S鎖,則事務(wù)T可以讀A但不能修改A雁仲,其他事務(wù)只能再對(duì)A加S鎖崎脉,而不能加X鎖,直到T釋放A上的S鎖伯顶。這保證了其他事務(wù)可以讀A囚灼,但在T釋放A上的S鎖之前不能對(duì)A做任何修改骆膝。
  • 排他鎖(X):又稱寫鎖。允許獲取排他鎖的事務(wù)更新數(shù)據(jù)灶体,阻止其他事務(wù)取得相同的數(shù)據(jù)集共享讀鎖和排他寫鎖阅签。若事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上X鎖,事務(wù)T可以讀A也可以修改A蝎抽,其他事務(wù)不能再對(duì)A加任何鎖政钟,直到T釋放A上的鎖。

對(duì)于排他鎖大家的理解可能就有些差別樟结,我當(dāng)初就犯了一個(gè)錯(cuò)誤养交,以為排他鎖鎖住一行數(shù)據(jù)后,其他事務(wù)就不能讀取和修改該行數(shù)據(jù)瓢宦,其實(shí)不是這樣的碎连。排他鎖指的是一個(gè)事務(wù)在一行數(shù)據(jù)加上排他鎖后,其他事務(wù)不能再在其上加其他的鎖驮履。mysql InnoDB引擎默認(rèn)的修改數(shù)據(jù)語(yǔ)句:update,delete,insert都會(huì)自動(dòng)給涉及到的數(shù)據(jù)加上排他鎖鱼辙,select語(yǔ)句默認(rèn)不會(huì)加任何鎖類型,如果加排他鎖可以使用select …for update語(yǔ)句玫镐,加共享鎖可以使用select … lock in share mode語(yǔ)句倒戏。所以加過(guò)排他鎖的數(shù)據(jù)行在其他事務(wù)中是不能修改數(shù)據(jù)的,也不能通過(guò)for update和lock in share mode鎖的方式查詢數(shù)據(jù)恐似,但可以直接通過(guò)select …from…查詢數(shù)據(jù)杜跷,因?yàn)槠胀ú樵儧]有任何鎖機(jī)制。

意向鎖:另外矫夷,為了允許行鎖和表鎖共存葛闷,實(shí)現(xiàn)多粒度鎖機(jī)制,InnoDB還有兩種內(nèi)部使用的意向鎖(Intention Locks)口四,這兩種意向鎖都是表鎖孵运。

  • 意向共享鎖(IS):事務(wù)打算給數(shù)據(jù)行共享鎖,事務(wù)在給一個(gè)數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖蔓彩。
  • 意向排他鎖(IX):事務(wù)打算給數(shù)據(jù)行加排他鎖治笨,事務(wù)在給一個(gè)數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖。

加鎖方法:意向鎖是InnoDB自動(dòng)加的赤嚼,不需用戶干預(yù)旷赖。對(duì)于UPDATE、DELETE和INSERT語(yǔ)句更卒,InnoDB會(huì)自動(dòng)給涉及數(shù)據(jù)集加排他鎖(X)等孵;對(duì)于普通SELECT語(yǔ)句,InnoDB不會(huì)加任何鎖蹂空。
事務(wù)可以通過(guò)以下語(yǔ)句顯式給記錄集加共享鎖或排他鎖:

共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
排他鎖(X):SELECT * FROM table_name WHERE ... FOR UPDATE

行鎖實(shí)現(xiàn)方式:InnoDB行鎖是通過(guò)給索引上的索引項(xiàng)加鎖來(lái)實(shí)現(xiàn)的俯萌,只有通過(guò)索引條件檢索數(shù)據(jù)果录,InnoDB才使用行級(jí)鎖,否則咐熙,InnoDB將使用表鎖弱恒!
(1)在不通過(guò)索引條件查詢的時(shí)候,InnoDB確實(shí)使用的是表鎖棋恼,而不是行鎖返弹。
(2)由于MySQL的行鎖是針對(duì)索引加的鎖,不是針對(duì)記錄加的鎖爪飘,所以雖然是訪問不同行的記錄义起,但是如果是使用相同的索引鍵,是會(huì)出現(xiàn)鎖沖突的师崎。
(3)當(dāng)表有多個(gè)索引的時(shí)候默终,不同的事務(wù)可以使用不同的索引鎖定不同的行,另外抡诞,不論是使用主鍵索引穷蛹、唯一索引或普通索引土陪,InnoDB都會(huì)使用行鎖來(lái)對(duì)數(shù)據(jù)加鎖昼汗。
(4)即便在條件中使用了索引字段,但是否使用索引來(lái)檢索數(shù)據(jù)是由MySQL通過(guò)判斷不同執(zhí)行計(jì)劃的代價(jià)來(lái)決 定的鬼雀,如果MySQL認(rèn)為全表掃描效率更高顷窒,比如對(duì)一些很小的表,它就不會(huì)使用索引源哩,這種情況下InnoDB將使用表鎖鞋吉,而不是行鎖。

6励烦、那你知道什么是間隙鎖嗎谓着?

當(dāng)我們用范圍條件而不是相等條件檢索數(shù)據(jù),并請(qǐng)求共享或排他鎖時(shí)坛掠,InnoDB會(huì)給符合條件的已有數(shù)據(jù)記錄的 索引項(xiàng)加鎖赊锚;對(duì)于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做“間隙(GAP)”屉栓,InnoDB也會(huì)對(duì)這個(gè)“間隙”加鎖舷蒲,這種鎖機(jī)制就是所謂的間隙鎖 (Next-Key鎖)。

(1)舉例來(lái)說(shuō)友多,假如emp表中只有101條記錄牲平,其empid的值分別是 1,2,…,100,101,下面的SQL:

Select * from  emp where empid > 100 for update;

是一個(gè)范圍條件的檢索域滥,InnoDB不僅會(huì)對(duì)符合條件的empid值為101的記錄加鎖纵柿,也會(huì)對(duì)empid大于101(這些記錄并不存在)的“間隙”加鎖蜈抓。

(2)InnoDB除了通過(guò)范圍條件加鎖時(shí)使用間隙鎖外,如果使用相等條件請(qǐng)求給一個(gè)不存在的記錄加鎖昂儒,InnoDB也會(huì)使用間隙鎖资昧!
假設(shè)emp表中只有101條記錄,其empid的值分別是1,2,……,100,101荆忍。 在一個(gè)事務(wù)中執(zhí)行如下語(yǔ)句加鎖:

Select * from  emp where empid > 100 for update;

在另一個(gè)事務(wù)中格带,執(zhí)行如下語(yǔ)句會(huì)出現(xiàn)鎖等待的情況

insert into emp(empid,...) values (201,...);
7、InnoDB使用間隙鎖的目的:
  • (1)防止幻讀刹枉,以滿足相關(guān)隔離級(jí)別的要求叽唱;
  • (2)滿足恢復(fù)和復(fù)制的需要:
    MySQL 通過(guò) BINLOG 錄入執(zhí)行成功的 INSERT、UPDATE微宝、DELETE 等更新數(shù)據(jù)的 SQL 語(yǔ)句棺亭,并由此實(shí)現(xiàn) MySQL 數(shù)據(jù)庫(kù)的恢復(fù)和主從復(fù)制。MySQL 的恢復(fù)機(jī)制(復(fù)制其實(shí)就是在 Slave Mysql 不斷做基于 BINLOG 的恢復(fù))有以下特點(diǎn):

一是 MySQL 的恢復(fù)是 SQL 語(yǔ)句級(jí)的蟋软,也就是重新執(zhí)行 BINLOG 中的 SQL 語(yǔ)句镶摘。
二是 MySQL 的 Binlog 是按照事務(wù)提交的先后順序記錄的, 恢復(fù)也是按這個(gè)順序進(jìn)行的岳守。

由此可見凄敢,MySQL 的恢復(fù)機(jī)制要求:在一個(gè)事務(wù)未提交前,其他并發(fā)事務(wù)不能插入滿足其鎖定條件的任何記錄湿痢,也就是不允許出現(xiàn)幻讀涝缝。

四、Mysql優(yōu)化

1譬重、SQL優(yōu)化主要分5個(gè)方向:SQL語(yǔ)句跟索引拒逮、表結(jié)構(gòu)設(shè)計(jì)、系統(tǒng)配置臀规、硬件配置滩援、數(shù)據(jù)庫(kù)架構(gòu)擴(kuò)展

  • (1)SQL語(yǔ)句跟索引:①最大化利用索引 ②盡可能避免全表掃描 ③減少無(wú)效數(shù)據(jù)的查詢
  • (2)表結(jié)構(gòu)設(shè)計(jì):①表設(shè)計(jì)符合三范式 ②選擇合適的數(shù)據(jù)類型
  • (3)系統(tǒng)配置:①選擇合適的存儲(chǔ)引擎 ②系統(tǒng)內(nèi)核優(yōu)化(Mysql主要運(yùn)行在Linux上)
  • (4)硬件配置:①加大物理內(nèi)存 ②使用SSD硬盤代替SAS硬盤 ,畢竟數(shù)據(jù)庫(kù)的壓力主要來(lái)自磁盤I/O方面
  • (5)數(shù)據(jù)庫(kù)架構(gòu)擴(kuò)展:①讀寫分離 ②分庫(kù)分表分區(qū) ③給數(shù)據(jù)庫(kù)增加緩存系統(tǒng)
2塔嬉、你們數(shù)據(jù)量級(jí)多大玩徊?分庫(kù)分表分區(qū)怎么做的?

分區(qū):就是把一張表的數(shù)據(jù)分成N個(gè)區(qū)塊邑遏,在邏輯上看最終只是一張表佣赖,但底層是由N個(gè)物理區(qū)塊組成的。
分表:就是把一張表按一定的規(guī)則分解成N個(gè)具有獨(dú)立存儲(chǔ)空間的實(shí)體表记盒。
分庫(kù):一旦分表憎蛤,一個(gè)庫(kù)中的表會(huì)越來(lái)越多。
首先分庫(kù)分表分為垂直和水平兩個(gè)方式,一般來(lái)說(shuō)我們拆分的順序是先垂直后水平俩檬。

3萎胰、那分表后的ID怎么保證唯一性的呢?

(1)設(shè)定步長(zhǎng)棚辽,比如1-1024張表我們分別設(shè)定1-1024的基礎(chǔ)步長(zhǎng)技竟,這樣主鍵落到不同的表就不會(huì)沖突了。
(2)分布式ID屈藐,自己實(shí)現(xiàn)一套分布式ID生成算法或者使用開源的比如雪花算法這種榔组。
(3)分表后不使用主鍵作為查詢依據(jù),而是每張表單獨(dú)新增一個(gè)字段作為唯一主鍵使用联逻,比如訂單表訂單號(hào)是唯一的搓扯,不管最終落在哪張表都基于訂單號(hào)作為查詢依據(jù),更新也一樣包归。

4锨推、數(shù)據(jù)庫(kù)三大范式
  • 第一范式:保證數(shù)據(jù)的原子性,數(shù)據(jù)庫(kù)表中的字段不可再分
  • 第二范式:消除部分依賴公壤,非主鍵列完全依賴于主鍵,而不能是依賴于主鍵的一部分(主要針對(duì)聯(lián)合主鍵而言)
  • 第三范式:消除傳遞依賴换可,非主鍵列只依賴于主鍵,不依賴于其他非主鍵

五、Mysql主從同步(讀寫分離厦幅、數(shù)據(jù)備份)

1沾鳄、說(shuō)說(shuō)mysql主從同步怎么做的吧?

(1)master數(shù)據(jù)發(fā)生變化慨削,提交完事務(wù)后洞渔,寫入binlog
(2)slave連接到master套媚,獲取binlog
(3)master創(chuàng)建dump線程缚态,推送binglog到slave
(4)slave啟動(dòng)一個(gè)IO線程讀取同步過(guò)來(lái)的master的binlog,記錄到relay log中繼日志中
(5)slave再開啟一個(gè)sql線程讀取relay log事件并在slave執(zhí)行堤瘤,完成同步
(6)slave記錄自己的binglog

.Master 數(shù)據(jù)庫(kù)只要發(fā)生變化玫芦,立馬記錄到Binary log 日志文件中
2.Slave數(shù)據(jù)庫(kù)啟動(dòng)一個(gè)I/O thread連接Master數(shù)據(jù)庫(kù),請(qǐng)求Master變化的二進(jìn)制日志
3.Slave I/O獲取到的二進(jìn)制日志本辐,保存到自己的Relay log 日志文件中桥帆。
4.Slave 有一個(gè) SQL thread定時(shí)檢查Realy log是否變化,變化那么就更新數(shù)據(jù)

由于mysql默認(rèn)的復(fù)制方式是異步的慎皱,主庫(kù)把日志發(fā)送給從庫(kù)后不關(guān)心從庫(kù)是否已經(jīng)處理老虫,這樣會(huì)產(chǎn)生一個(gè)問題就是假設(shè)主庫(kù)掛了,從庫(kù)處理失敗了茫多,這時(shí)候從庫(kù)升為主庫(kù)后祈匙,日志就丟失了。由此產(chǎn)生兩個(gè)概念。

  • 全同步復(fù)制:主庫(kù)寫入binlog后強(qiáng)制同步日志到從庫(kù)夺欲,所有的從庫(kù)都執(zhí)行完成后才返回給客戶端跪帝,但是很顯然這個(gè)方式的話性能會(huì)受到嚴(yán)重影響。
  • 半同步復(fù)制:和全同步不同的是些阅,半同步復(fù)制的邏輯是這樣伞剑,從庫(kù)寫入日志成功后返回ACK確認(rèn)給主庫(kù),主庫(kù)收到至少一個(gè)從庫(kù)的確認(rèn)就認(rèn)為寫操作完成市埋。
2黎泣、主從同步/復(fù)制的好處
  • (1)實(shí)現(xiàn)服務(wù)器負(fù)載均衡(讀寫分離)
  • (2)通過(guò)復(fù)制實(shí)現(xiàn)數(shù)據(jù)的異地備份
  • (3)提高數(shù)據(jù)庫(kù)系統(tǒng)的可用性

六、執(zhí)行計(jì)劃

使用 MySQL 的執(zhí)行計(jì)劃來(lái)查看 SQL 語(yǔ)句的執(zhí)行效率

EXPLAIN SELECT * FROM test_aa WHERE id = 1

1缤谎、select_type:查詢的類型聘裁,主要是用于區(qū)分普通查詢、聯(lián)合查詢弓千、子查詢等衡便。簡(jiǎn)單的 select 查詢,查詢中不包含子查詢或者 union

  • PRIMARY:查詢中包含子部分洋访,最外層查詢則被標(biāo)記為 primary
  • SUBQUERY:SUBQUERY 表示在 select 或 where 列表中包含了子查詢镣陕,
  • UNION:表示 union 中的第二個(gè)或后面的 select 語(yǔ)句

2、table:查詢涉及到的表姻政。

3呆抑、type :訪問類型,SQL 查詢優(yōu)化中一個(gè)很重要的指標(biāo)汁展,結(jié)果值從好到壞依次是:system > const > eq_ref > ref > range > index > ALL鹊碍。

  • system:系統(tǒng)表,少量數(shù)據(jù)食绿,往往不需要進(jìn)行磁盤IO
  • const:常量連接
  • eq_ref:主鍵索引(primary key)或者非空唯一索引(unique not null)等值掃描
  • ref:非主鍵非唯一索引等值掃描
  • range:范圍掃描
  • index:索引樹掃描
  • ALL:全表掃描(full table scan)

4侈咕、possible_keys:查詢過(guò)程中有可能用到的索引。

5器紧、key:實(shí)際使用的索引耀销,如果為 NULL ,則沒有使用索引铲汪。

6熊尉、rows:根據(jù)表統(tǒng)計(jì)信息或者索引選用情況,大致估算出找到所需的記錄所需要讀取的行數(shù)掌腰。

7狰住、filtered:表示返回結(jié)果的行數(shù)占需讀取行數(shù)的百分比, filtered 的值越大越好齿梁。

8催植、Extra :十分重要的額外信息。

  • Using index:表示 SQL 操作中使用了覆蓋索引(Covering Index),避免了訪問表的數(shù)據(jù)行查邢,效率高蔗崎。
  • Using index condition:表示 SQL 操作命中了索引,但不是所有的列數(shù)據(jù)都在索引樹上扰藕,還需要訪問實(shí)際的行記錄缓苛。
  • Using where:表示 SQL 操作使用了 where 過(guò)濾條件。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末邓深,一起剝皮案震驚了整個(gè)濱河市未桥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌芥备,老刑警劉巖冬耿,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異萌壳,居然都是意外死亡亦镶,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門袱瓮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)缤骨,“玉大人,你說(shuō)我怎么就攤上這事尺借“砥穑” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵燎斩,是天一觀的道長(zhǎng)虱歪。 經(jīng)常有香客問我,道長(zhǎng)栅表,這世上最難降的妖魔是什么笋鄙? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮谨读,結(jié)果婚禮上局装,老公的妹妹穿的比我還像新娘。我一直安慰自己劳殖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布拨脉。 她就那樣靜靜地躺著哆姻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪玫膀。 梳的紋絲不亂的頭發(fā)上矛缨,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼箕昭。 笑死灵妨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的落竹。 我是一名探鬼主播泌霍,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼述召!你這毒婦竟也來(lái)了朱转?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤积暖,失蹤者是張志新(化名)和其女友劉穎藤为,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夺刑,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缅疟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遍愿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窿吩。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖错览,靈堂內(nèi)的尸體忽然破棺而出纫雁,到底是詐尸還是另有隱情,我是刑警寧澤倾哺,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布轧邪,位于F島的核電站,受9級(jí)特大地震影響羞海,放射性物質(zhì)發(fā)生泄漏忌愚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一却邓、第九天 我趴在偏房一處隱蔽的房頂上張望硕糊。 院中可真熱鬧,春花似錦腊徙、人聲如沸简十。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)螟蝙。三九已至,卻和暖如春民傻,著一層夾襖步出監(jiān)牢的瞬間胰默,已是汗流浹背场斑。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牵署,地道東北人漏隐。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像奴迅,于是被迫代替她去往敵國(guó)和親青责。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1.什么Mysql的事務(wù)半沽?事務(wù)的四大特性爽柒?事務(wù)帶來(lái)的什么問題? Mysql中事務(wù)的隔離級(jí)別分為四大等級(jí):讀未提交(...
    long_c2b7閱讀 506評(píng)論 0 0
  • 以下是我面試了無(wú)數(shù)公司總結(jié)出來(lái)的個(gè)人感覺被問頻率最高最有用的20道Mysql面試題者填,分享出來(lái)給大家做參考浩村。希望大家...
    Java柚子閱讀 455評(píng)論 0 6
  • 1. MySQL 中 varchar 與 char 的區(qū)別?varchar(50) 中的 50 代表的涵義占哟? va...
    lj72808up閱讀 88評(píng)論 0 0
  • 最新阿里MySQL面試題目45道心墅,以及學(xué)習(xí)路線分享! - 簡(jiǎn)書 2018最新mysql數(shù)據(jù)庫(kù)優(yōu)化面試 mysql索...
    任嘉平生愿閱讀 4,932評(píng)論 0 3
  • 夜鶯2517閱讀 127,720評(píng)論 1 9