MySQL 高頻 100 問【建議收藏】
本文主要受眾為開發(fā)人員,所以不涉及到MySQL的服務(wù)部署等操作,且內(nèi)容較多,大家準(zhǔn)備好耐心和瓜子礦泉水.
索引相關(guān)
hash索引進(jìn)行等值查詢更快(一般情況下),但是卻無法進(jìn)行范圍查詢.
hash索引不支持使用索引進(jìn)行排序,原理同上.
hash索引不支持模糊查詢以及多列索引的最左前綴匹配.原理也是因?yàn)閔ash函數(shù)的不可預(yù)測(cè).AAAA和AAAAB的索引沒有相關(guān)性.
hash索引任何時(shí)候都避免不了回表查詢數(shù)據(jù),而B+樹在符合某些條件(聚簇索引,覆蓋索引等)的時(shí)候可以只通過索引完成查詢.
hash索引雖然在等值查詢上較快,但是不穩(wěn)定.性能不可預(yù)測(cè),當(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是變長(zhǎng)的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)然比較慢.
我們可以修改為
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ù).
從需求的角度減少這種請(qǐng)求….主要是不做類似的需求(直接跳轉(zhuǎn)到幾百萬頁之后的具體某一頁.只允許逐頁查看或者按照給定的路線走,這樣可預(yù)測(cè),可緩存)以及防止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)題和摘要id-摘要,id-內(nèi)容.當(dāng)用戶點(diǎn)擊詳情,那主鍵再來取一次內(nèi)容即可.而增加的存儲(chǔ)量只是很小的主鍵字段.代價(jià)很小.怎么接私活?這個(gè)渠道你100%有用!請(qǐng)收藏!
喜歡文章,點(diǎn)個(gè)在看


