[靈魂拷問] MySQL面試高頻100問(工程師方向)
點(diǎn)擊上方“碼農(nóng)突圍”,馬上關(guān)注
這里是碼農(nóng)充電第一站,回復(fù)“666”,獲取一份專屬大禮包
真愛,請?jiān)O(shè)置“星標(biāo)”或點(diǎn)個(gè)“在看”

來源:juejin.im/post/5d351303f265da1bd30596f9
前言
索引相關(guān)
hash索引進(jìn)行等值查詢更快(一般情況下),但是卻無法進(jìn)行范圍查詢.
hash索引不支持使用索引進(jìn)行排序,原理同上.
hash索引不支持模糊查詢以及多列索引的最左前綴匹配.原理也是因?yàn)閔ash函數(shù)的不可預(yù)測.AAAA和AAAAB的索引沒有相關(guān)性.
hash索引任何時(shí)候都避免不了回表查詢數(shù)據(jù),而B+樹在符合某些條件(聚簇索引,覆蓋索引等)的時(shí)候可以只通過索引完成查詢.
hash索引雖然在等值查詢上較快,但是不穩(wěn)定.性能不可預(yù)測,當(dāng)某個(gè)鍵值存在大量重復(fù)的時(shí)候,發(fā)生hash碰撞,此時(shí)效率可能極差.而B+樹的查詢效率比較穩(wěn)定,對(duì)于所有的查詢都是從根節(jié)點(diǎn)到葉子節(jié)點(diǎn),且樹的高度較低.
select age from employee where age < 20的查詢時(shí),在索引的葉子節(jié)點(diǎn)上,已經(jīng)包含了age信息,不會(huì)再次進(jìn)行回表查詢.使用不等于查詢,
列參與了數(shù)學(xué)運(yùn)算或者函數(shù)
在字符串like時(shí)左邊是通配符.類似于'%aaa'.
當(dāng)mysql分析全表掃描比使用索引快的時(shí)候不使用索引.
當(dāng)使用聯(lián)合索引,前面一個(gè)條件為范圍查詢,后面的即使符合最左前綴原則,也無法使用索引.
事務(wù)相關(guān)
臟讀: A事務(wù)讀取到了B事務(wù)未提交的內(nèi)容,而B事務(wù)后面進(jìn)行了回滾.
不可重復(fù)讀: 當(dāng)設(shè)置A事務(wù)只能讀取B事務(wù)已經(jīng)提交的部分,會(huì)造成在A事務(wù)內(nèi)的兩次查詢,結(jié)果竟然不一樣,因?yàn)樵诖似陂gB事務(wù)進(jìn)行了提交操作.
幻讀: A事務(wù)讀取了一個(gè)范圍的內(nèi)容,而同時(shí)B事務(wù)在此期間插入了一條數(shù)據(jù).造成"幻覺".
未提交讀(READ UNCOMMITTED)
已提交讀(READ COMMITTED)
REPEATABLE READ(可重復(fù)讀)
SERIALIZABLE(可串行化)
表結(jié)構(gòu)設(shè)計(jì)

If you define a PRIMARY KEY on your table, InnoDB uses it as the clustered index. If you do not define a PRIMARY KEY for your table, MySQL picks the first UNIQUE index that has only NOT NULL columns as the primary key and InnoDB uses it as the clustered index.
NULL columns require additional space in the rowto record whether their values are NULL. For MyISAM tables, each NULL columntakes one bit extra, rounded up to the nearest byte.
存儲(chǔ)引擎相關(guān)
InnoDB和MyISAM有什么區(qū)別?
InnoDB支持事物,而MyISAM不支持事物
InnoDB支持行級(jí)鎖,而MyISAM支持表級(jí)鎖
InnoDB支持MVCC, 而MyISAM不支持
InnoDB支持外鍵,而MyISAM不支持
InnoDB不支持全文索引,而MyISAM支持。
零散問題
char(10)的空間,那么無論實(shí)際存儲(chǔ)多少內(nèi)容.該字段都占用10個(gè)字符,而varchar是變長的,也就是說申請的只是最大長度,占用的空間為實(shí)際字符長度+1,最后一個(gè)字符存儲(chǔ)使用了多長的空間.statement模式下,記錄單元為語句.即每一個(gè)sql造成的影響會(huì)記錄.由于sql的執(zhí)行是有上下文的,因此在保存的時(shí)候需要保存相關(guān)的信息,同時(shí)還有一些使用了函數(shù)之類的語句無法被記錄復(fù)制.
row級(jí)別下,記錄單元為每一行的改動(dòng),基本是可以全部記下來但是由于很多操作,會(huì)導(dǎo)致大量行的改動(dòng)(比如alter table),因此這種模式的文件保存的信息太多,日志量太大.
mixed. 一種折中的方案,普通操作使用statement記錄,當(dāng)無法使用statement的時(shí)候使用row.
數(shù)據(jù)庫層面,這也是我們主要集中關(guān)注的(雖然收效沒那么大),類似于
select * from table where age > 20 limit 1000000,10這種查詢其實(shí)也是有可以優(yōu)化的余地的. 這條語句需要load1000000數(shù)據(jù)然后基本上全部丟棄,只取10條當(dāng)然比較慢. 當(dāng)時(shí)我們可以修改為select * from table where id in (select id from table where age > 20 limit 1000000,10).這樣雖然也load了一百萬的數(shù)據(jù),但是由于索引覆蓋,要查詢的所有字段都在索引中,所以速度會(huì)很快. 同時(shí)如果ID連續(xù)的好,我們還可以select * from table where id > 1000000 limit 10,效率也是不錯(cuò)的,優(yōu)化的可能性有許多種,但是核心思想都一樣,就是減少load的數(shù)據(jù).從需求的角度減少這種請求….主要是不做類似的需求(直接跳轉(zhuǎn)到幾百萬頁之后的具體某一頁.只允許逐頁查看或者按照給定的路線走,這樣可預(yù)測,可緩存)以及防止ID泄漏且連續(xù)被人惡意攻擊.

首先分析語句,看看是否load了額外的數(shù)據(jù),可能是查詢了多余的行并且拋棄掉了,可能是加載了許多結(jié)果中并不需要的列,對(duì)語句進(jìn)行分析以及重寫.
分析語句的執(zhí)行計(jì)劃,然后獲得其使用索引的情況,之后修改語句或者修改索引,使得語句可以盡可能的命中索引.
如果對(duì)語句的優(yōu)化已經(jīng)無法進(jìn)行,可以考慮表中的數(shù)據(jù)量是否太大,如果是的話可以進(jìn)行橫向或者縱向的分表.
id-摘要-內(nèi)容.而系統(tǒng)中的展示形式是刷新出一個(gè)列表,列表中僅包含標(biāo)題和摘要,當(dāng)用戶點(diǎn)擊某篇文章進(jìn)入詳情時(shí)才需要正文內(nèi)容.此時(shí),如果數(shù)據(jù)量大,將內(nèi)容這個(gè)很大且不經(jīng)常使用的列放在一起會(huì)拖慢原表的查詢速度.我們可以將上面的表分為兩張.id-摘要,id-內(nèi)容.當(dāng)用戶點(diǎn)擊詳情,那主鍵再來取一次內(nèi)容即可.而增加的存儲(chǔ)量只是很小的主鍵字段.代價(jià)很小.最后,這里再跟大家推薦一本程序員必知的硬核基礎(chǔ)知識(shí),這是一本非常入門的經(jīng)典 PDF,看完能讓你對(duì)計(jì)算機(jī)有一個(gè)基礎(chǔ)的了解和入門,是培養(yǎng)你?內(nèi)核?的基礎(chǔ),我們看下目錄大綱





計(jì)算機(jī)基礎(chǔ)?來領(lǐng)取這本 PDF。最近熱文
? 突發(fā)!Windows XP 源代碼泄露 ???為什么我強(qiáng)烈建議大家使用 Linux 開發(fā)? ???靈魂一問:一個(gè)TCP連接可以發(fā)多少個(gè)HTTP請求? ???保送北大,連發(fā)三篇Science,這位80后川妹子近日再發(fā)重磅級(jí)研究成果! 最近整理了一份大廠算法刷題指南,包括一些刷題技巧,在知乎上已經(jīng)有上萬贊。同時(shí)還整理了一份6000頁面試筆記。關(guān)注下面公眾號(hào),在公眾號(hào)內(nèi)回復(fù)「刷題」,即可免費(fèi)獲??!回復(fù)「加群」,可以邀請你加入讀者群!
明天見(??ω??)??
