无法从套接字读取更多的数据 oracle_小伙面试时被追问数据库优化,面试前如何埋点反杀?
前言
周五的早高峰, 各地軟件園地鐵站里中出現(xiàn)了不少穿著長(zhǎng)袖加絨格子衫, 背雙肩電腦包的年輕碼農(nóng), 現(xiàn)在節(jié)氣正值 [ 小雪 ] , 11月的全國(guó)性突然降溫 , 讓經(jīng)歷過(guò)996摧殘的猿們一出地鐵站就凍的打了個(gè)激靈 , 很慶幸的告訴大家距離放年假還剩不到 37 個(gè)工作日, 要買(mǎi)火車(chē)票的趕緊預(yù)約搶, 要租男朋友的趕緊聯(lián)系我.
---
前幾天我, 張大胖 , Mason 下班約好一起去吃海X撈火鍋, 大家去了都圍到到一張小火鍋?zhàn)雷由? 服務(wù)員把菜單遞給我們.這時(shí)張大胖拿著菜單就開(kāi)口了, "今天不要點(diǎn)綠色的菜, 我最近手里的股票全部綠油油的 太護(hù)眼了, 先來(lái)個(gè) 牛油麻辣鍋底! 來(lái)3份 草原牛肉片, 來(lái)1份牛肉丸子, 來(lái)3份牛楠, 剩下的你們點(diǎn)吧".我吸了口氣說(shuō) "你這點(diǎn)全是肉, 合著哥幾個(gè)今天陪你來(lái)長(zhǎng)膘了" .Mason 看我倆要掐起來(lái) 趕緊接上: "要不來(lái)一份西蘭花, 一份花菜, 這樣看著火鍋湯色也不錯(cuò)~".張大胖皺了下眉毛, 嘆了口氣 "我前段時(shí)間去面試, 被面試官連環(huán)追問(wèn), Mysql數(shù)據(jù)庫(kù)優(yōu)化 一路追問(wèn)到 B+樹(shù)索引底層 ,我恨不得當(dāng)場(chǎng)GG, 今天你又點(diǎn)樹(shù), 想想就頭痛 ~" .Mason 笑了笑說(shuō) "這個(gè)Mysql B+索引, 你每天都在用但是不知道它原理, 面試官估計(jì)心里在犯嘀咕, 這個(gè)人其它方面都合格, 但是就怕 '新同事來(lái)了,數(shù)據(jù)庫(kù)變慢了' 正確的使用并理解數(shù)據(jù)庫(kù)索引就是最好的優(yōu)化反之"張大胖聽(tīng)的一頭霧水然后問(wèn) 到底怎么表述數(shù)據(jù)庫(kù)優(yōu)化給面試官才能抱的Offer歸呢 ?Mason 喝了口水說(shuō)道 "那今天我們就邊打邊爐邊聊聊數(shù)據(jù)庫(kù)優(yōu)化, 我以前專(zhuān)門(mén)整理過(guò)數(shù)據(jù)庫(kù)優(yōu)化相關(guān)的知識(shí)"我急忙打斷說(shuō) "要不先上菜吧, 中午就吃了碗熱干面, 我現(xiàn)在太餓了"
數(shù)據(jù)庫(kù)優(yōu)化主要有3個(gè)方面
- SQL層面 使用 Join 替代子查詢(xún) (子程序查詢(xún)結(jié)果會(huì)形成臨時(shí)表) 正確書(shū)寫(xiě)SQL 使索引生效 SELECT語(yǔ)句務(wù)必指明字段名稱(chēng) 當(dāng)只需要一條數(shù)據(jù)的時(shí)候,使用limit 1 排序字段沒(méi)有用到索引,就盡量少排序 Ps: 平時(shí)寫(xiě)SQL ,多用 EXPLAIN 檢查SQL質(zhì)量 ...
https://zhuanlan.zhihu.com/p/58065348
- 表結(jié)構(gòu)層面 設(shè)計(jì)表時(shí)重中之重就是考慮這張表, 大概有什么操作要上什么索引. 增加冗余字段和中間表 (空間換時(shí)間) 確定字段正確存儲(chǔ)范圍 ....
https://www.zhihu.com/question/19719997/answer/154809252
- 物理架構(gòu)層面 數(shù)據(jù)庫(kù)緩存配置 讀寫(xiě)分離 當(dāng)數(shù)據(jù)庫(kù)讀遠(yuǎn)大于寫(xiě),查詢(xún)多的情況,就可以考慮主數(shù)據(jù)負(fù)責(zé)寫(xiě)操作,從數(shù)據(jù)庫(kù)負(fù)責(zé)讀操作,一主多重,從而把數(shù)據(jù)讀寫(xiě)分離,最后還可以結(jié)合redis等緩存來(lái)配合分擔(dān)數(shù)據(jù)的讀操作,大大的降低數(shù)據(jù)庫(kù)的壓力。 分庫(kù)分表《阿里巴巴Java開(kāi)發(fā)手冊(cè)》提出單表行數(shù)超過(guò)500萬(wàn)行或者單表容量超過(guò)2GB,才推薦分庫(kù)分表。性能由綜合因素決定,拋開(kāi)業(yè)務(wù)復(fù)雜度,影響程度依次是硬件配置、MySQL配置、數(shù)據(jù)表設(shè)計(jì)、索引優(yōu)化。500萬(wàn)這個(gè)值僅供參考,并非鐵律。 對(duì)大表進(jìn)行歷史歸檔, 比如美團(tuán)外賣(mài)訂單只能看近一年的訂單...
https://zhuanlan.zhihu.com/p/88139202
MySQL B+ Tree 索引原理
先來(lái)看看 這兩種樹(shù)形數(shù)據(jù)結(jié)構(gòu)模擬自增ID索引場(chǎng)景 Ps: 大家有空也可以玩玩 https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
兩款經(jīng)典樹(shù)形數(shù)據(jù)結(jié)構(gòu),
- 左 : 二叉查找樹(shù), 右 : 平衡二叉樹(shù) 二叉查找樹(shù)概述 若任意節(jié)點(diǎn)的左子樹(shù)不空,則左子樹(shù)上所有結(jié)點(diǎn)的值均小于它的根結(jié)點(diǎn)的值; 若任意節(jié)點(diǎn)的右子樹(shù)不空,則右子樹(shù)上所有結(jié)點(diǎn)的值均大于它的根結(jié)點(diǎn)的值; 任意節(jié)點(diǎn)的左、右子樹(shù)也分別為二叉查找樹(shù); 沒(méi)有鍵值相等的節(jié)點(diǎn)。 假設(shè)用來(lái)做索引: 單一子樹(shù)數(shù)據(jù)發(fā)生變化時(shí)無(wú)法進(jìn)行左旋右旋平衡, 會(huì)導(dǎo)致二叉樹(shù)嚴(yán)重不平衡, 惡劣情況查詢(xún)復(fù)雜度由 O(log n) 跌為 O(n) 的鏈表.
- 平衡二叉樹(shù)概述 它必須是二叉查找樹(shù) . 每個(gè)節(jié)點(diǎn)的左子樹(shù)和右子樹(shù)的高度差至多為1。 每次數(shù)據(jù)發(fā)生變換會(huì)進(jìn)行 對(duì)應(yīng)的 左旋 或 右旋 來(lái)平衡樹(shù)的結(jié)構(gòu). 有效保證了+ 查詢(xún)復(fù)雜度為 O(log n).
- 假設(shè)用來(lái)做索引: 1.在平衡二叉樹(shù)中, 一顆層級(jí)為 100 樹(shù), 找到最末端的節(jié)點(diǎn), 需要IO 100 次. IO效率很低., 2. 預(yù)加載關(guān)聯(lián)節(jié)點(diǎn)數(shù)據(jù)少, 每次加載IO只加載一個(gè)節(jié)點(diǎn), 每次IO操作一頁(yè) (4KB數(shù)據(jù)) 。
https://blog.csdn.net/qq_37934101/article/details/81160254
---
**綜上所述: 這兩種經(jīng)典樹(shù)形數(shù)據(jù)結(jié)構(gòu)都不是最理想的數(shù)據(jù)庫(kù)索引樹(shù), 當(dāng)當(dāng)當(dāng) !!!
大名鼎鼎的 B+樹(shù)就橫空出世了**
- B+ 樹(shù)定義 B+樹(shù)包含2種類(lèi)型的結(jié)點(diǎn):內(nèi)部結(jié)點(diǎn)(也稱(chēng)索引結(jié)點(diǎn))和葉子結(jié)點(diǎn)。根結(jié)點(diǎn)本身即可以是內(nèi)部結(jié)點(diǎn),也可以是葉子結(jié)點(diǎn)。根結(jié)點(diǎn)的關(guān)鍵字個(gè)數(shù)最少可以只有1個(gè)。 B+樹(shù)與B樹(shù)最大的不同是內(nèi)部結(jié)點(diǎn)不保存數(shù)據(jù),只用于索引,所有數(shù)據(jù)(或者說(shuō)記錄)都保存在葉子結(jié)點(diǎn)中。 m階B+樹(shù)表示了內(nèi)部結(jié)點(diǎn)最多有m-1個(gè)關(guān)鍵字(或者說(shuō)內(nèi)部結(jié)點(diǎn)最多有m個(gè)子樹(shù)),階數(shù)m同時(shí)限制了葉子結(jié)點(diǎn)最多存儲(chǔ)m-1個(gè)記錄。 內(nèi)部結(jié)點(diǎn)中的key都按照從小到大的順序排列,對(duì)于內(nèi)部結(jié)點(diǎn)中的一個(gè)key,左樹(shù)中的所有key都小于它,右子樹(shù)中的key都大于等于它。葉子結(jié)點(diǎn)中的記錄也按照key的大小排列。 每個(gè)葉子結(jié)點(diǎn)都存有相鄰葉子結(jié)點(diǎn)的指針,葉子結(jié)點(diǎn)本身依關(guān)鍵字的大小自小而大順序鏈接。
https://www.cnblogs.com/nullzx/p/8729425.html
- B+ 樹(shù)的特點(diǎn) 非葉子節(jié)點(diǎn)不存儲(chǔ) data, 只存儲(chǔ)索引 (冗余) 可放更多的索引. 葉子節(jié)點(diǎn)包括所有索引字段. 葉子節(jié)點(diǎn)用指針有序連接, 提高區(qū)間訪問(wèn)的性能. 常見(jiàn)的 B+樹(shù) 為三層, 每個(gè)節(jié)點(diǎn)磁盤(pán)存儲(chǔ)默認(rèn)大小 16KB, 索引節(jié)點(diǎn)存有多個(gè)索引和多個(gè)指針(一個(gè)索引為 bigint類(lèi)型約 8KB ,一個(gè)指針約 6 KB, 最多可存 1170個(gè)索引指針組合). 一次加載一個(gè)索引節(jié)點(diǎn)有效利于IO資源, 讀取任意葉子節(jié)點(diǎn)都只需 3次 IO操作.
- **B+ 樹(shù)在 MySQL 的應(yīng)用
綜上所述: 矮胖的B + 樹(shù) 恰好彌補(bǔ)了 瘦高平衡二叉樹(shù)的兩點(diǎn)不足. 層級(jí)少, IO預(yù)加載數(shù)據(jù)多.**
那在MySQL數(shù)據(jù)庫(kù)中是如何使用 B+ Tree 構(gòu)建自己的索引呢?
- InnoDB 索引方式 (部分內(nèi)容來(lái)自官網(wǎng))
InnoDB是一種兼顧了高可靠性和高性能的通用存儲(chǔ)引擎。在MySQL 5.7中,InnoDB是默認(rèn)的MySQL存儲(chǔ)引擎。除非您配置了其他默認(rèn)存儲(chǔ)引擎,否則發(fā)出CREATE TABLE不帶ENGINE= 子句的語(yǔ)句將創(chuàng)建一個(gè)InnoDB表。
InnoDB 的主要優(yōu)勢(shì)
- 它的DML操作遵循 ACID模型,并 具有具有 提交,回滾和 崩潰恢復(fù) 功能的事務(wù), 以保護(hù)用戶(hù)數(shù)據(jù)。有關(guān)更多信息,請(qǐng)參見(jiàn) 第14.2節(jié)“ InnoDB和ACID模型”。
- 行級(jí)鎖定和Oracle風(fēng)格的一致讀取可提高多用戶(hù)并發(fā)性和性能。有關(guān)更多信息,請(qǐng)參見(jiàn)第14.7節(jié)“ InnoDB鎖定和事務(wù)模型”。
- InnoDB表格將您的數(shù)據(jù)排列在磁盤(pán)上以基于主鍵優(yōu)化查詢(xún) 。每個(gè) InnoDB表都有一個(gè)稱(chēng)為聚集索引的主鍵索引,該索引 組織數(shù)據(jù)以最小化主鍵查找的I / O。有關(guān)更多信息,請(qǐng)參見(jiàn)第14.6.2.1節(jié)“聚集索引和二級(jí)索引”。
- 維護(hù)數(shù)據(jù) 完整性, InnoDB支持 FOREIGN KEY約束。使用外鍵檢查插入,更新和刪除操作,以確保它們不會(huì)導(dǎo)致不同表之間的不一致。有關(guān)更多信息,請(qǐng)參見(jiàn) 第13.1.18.6節(jié)“外鍵約束”。 在 test_innodb表中執(zhí)行此SQL 會(huì)如何使用 InnoDB 索引 ?
select * from test_innodb where name = 'to%' ``
- InnoDB 的缺點(diǎn) 5.7 以前不支持 全文檢索, 最常用索引, 除了它 其他MySQL 索引都被官方稱(chēng)作替代存儲(chǔ)引擎, 地位接近封神.
- 物理層面 (一張 test_innodb表默認(rèn)有 2個(gè)存儲(chǔ)文件組成) test_innodb.frm : 表結(jié)構(gòu)定義 testinnodb.ibd : 存放 testinnodb 表的數(shù)據(jù)和索引的文件
- 使用InnoDB表時(shí)的最佳做法 。 使用查詢(xún)頻率最高的一個(gè)或多個(gè)列為每個(gè)表 指定一個(gè)主鍵, 如果沒(méi)有明顯的主鍵,則指定一個(gè) 自動(dòng)增量值。 使用聯(lián)接時(shí),無(wú)論是基于多個(gè)表中相同的ID值,還是從多個(gè)表中提取數(shù)據(jù)。為了提高連接性能,請(qǐng)?jiān)谶B接列上定義 外鍵,并在每個(gè)表中使用相同的數(shù)據(jù)類(lèi)型聲明這些列。添加外鍵可確保對(duì)引用的列進(jìn)行索引,從而可以提高性能。外鍵還將刪除或更新傳播到所有受影響的表,并且如果父表中不存在相應(yīng)的ID,則可以防止在子表中插入數(shù)據(jù)。 關(guān)閉自動(dòng)提交。每秒提交數(shù)百次會(huì)限制性能(受存儲(chǔ)設(shè)備的寫(xiě)入速度限制)。 分組組相關(guān)的DML 操作成 交易,通過(guò)包圍他們START TRANSACTION和 COMMIT報(bào)表。雖然你不想過(guò)于頻繁地提交,你也不想發(fā)出的巨大的批次 INSERT, UPDATE或 DELETE陳述,不提交運(yùn)行小時(shí)。 不使用LOCK TABLES 語(yǔ)句。InnoDB可以一次處理多個(gè)會(huì)話,一次讀寫(xiě)同一張表,而無(wú)需犧牲可靠性或高性能。要獲得對(duì)一組行的排他性寫(xiě)訪問(wèn)權(quán)限,請(qǐng)使用 SELECT ... FOR UPDATE語(yǔ)法僅鎖定要更新的行。 啟用該 innodbfileper_table選項(xiàng)或使用常規(guī)表空間將表的數(shù)據(jù)和索引放入單獨(dú)的文件中,而不是 系統(tǒng)表空間中。
innodbfileper_table 默認(rèn)情況下啟用 該選項(xiàng)。 評(píng)估您的數(shù)據(jù)和訪問(wèn)模式是否受益于InnoDB表或頁(yè)面 壓縮功能。您可以在InnoDB不犧牲讀/寫(xiě)能力的情況下壓縮表。
- MyISAM 索引方式
創(chuàng)建的表占用的空間很小。表級(jí)鎖定限制了讀/寫(xiě)工作負(fù)載中的性能,因此它通常用于Web和數(shù)據(jù)倉(cāng)庫(kù)配置中的只讀或只讀工作負(fù)載中。
MyISAM 的主要優(yōu)勢(shì)
- 所有數(shù)據(jù)值均以低字節(jié)開(kāi)頭存儲(chǔ)。這使數(shù)據(jù)機(jī)和操作系統(tǒng)獨(dú)立。二進(jìn)制可移植性的唯一要求是機(jī)器使用二進(jìn)制補(bǔ)碼帶符號(hào)整數(shù)和IEEE浮點(diǎn)格式。這些要求已在主流機(jī)器中廣泛使用。二進(jìn)制兼容性可能不適用于有時(shí)具有特殊處理器的嵌入式系統(tǒng)。
先存儲(chǔ)低字節(jié)數(shù)據(jù)沒(méi)有明顯的速度損失;表行中的字節(jié)通常是未對(duì)齊的,按順序讀取未對(duì)齊的字節(jié)所需的處理要多于反向的順序。而且,與其他代碼相比,服務(wù)器中獲取列值的代碼不是時(shí)間緊迫的。 - 所有數(shù)字鍵值都先存儲(chǔ)高字節(jié),以實(shí)現(xiàn)更好的索引壓縮。
- 在支持大文件的文件系統(tǒng)和操作系統(tǒng)上,支持大文件。 在 test_myisam 表中執(zhí)行此SQL 會(huì)如何使用 MyISAM 索引 ?
select * from test_myisam where id = 20 `` - MyISAM 的缺點(diǎn) 不支持事務(wù), 僅支持 表級(jí)鎖,系統(tǒng)奔潰后,MyISAM恢復(fù)起來(lái)比較困難.
- 物理層面 (一張 test_myisam 表默認(rèn)有 3個(gè)存儲(chǔ)文件組成) test_myisam.frm : 表結(jié)構(gòu)定義 test_myisam.MYD : 表數(shù)據(jù) (文件后綴名全稱(chēng) Mysql Data) test_myisam.MYI : 表索引 (文件后綴名全稱(chēng) Mysql Index , 各字段索引之間獨(dú)立)
- Innodb VS Myisam 本質(zhì)上的區(qū)別
經(jīng)典數(shù)據(jù)庫(kù)優(yōu)化面試問(wèn)題
- 為什么索引結(jié)構(gòu)默認(rèn)使用B + Tree,而不是hash桶,二叉查找樹(shù),平衡二叉樹(shù)?
hash:雖然可以快速定位,但是沒(méi)有順序,IO復(fù)雜度高。二叉樹(shù):樹(shù)的高度不均勻,不能自平衡,查找效率跟數(shù)據(jù)有關(guān)(樹(shù)的高度),并且IO代價(jià)高。平衡二叉樹(shù):樹(shù)的高度隨著數(shù)據(jù)量增加而增加,IO代價(jià)高。
B-Tree: 常見(jiàn)的 B+樹(shù) 為三層, 每個(gè)節(jié)點(diǎn)磁盤(pán)存儲(chǔ)默認(rèn)大小 16KB, 索引節(jié)點(diǎn)存有多個(gè)索引和多個(gè)指針(一個(gè)索引為 bigint類(lèi)型約 8KB ,一個(gè)指針約 6 KB, 最多可存 1170個(gè)索引指針組合). 一次加載一個(gè)索引(16KB)節(jié)點(diǎn)有效利于IO資源, 讀取當(dāng)前索引任意葉子節(jié)點(diǎn)都只需 3次 IO操作.
- 下列這行SQL 不使用索引的原因 ?
select * from test_innodb where name = '%to%' ``
先問(wèn)是不是再問(wèn)為什么, 我們先建一張表測(cè)試一波, 全模糊匹配是否使用索引 !
-- auto-generated definitioncreate table test_fuzzytext_index( id int auto_increment primary key, context text not null, context_fulltext text not null, context_index varchar(100) not null);給 testfuzzytextindex 的 文本類(lèi)型的一些字段 加上索引形成和不加索引的對(duì)照組 !
-- 0. context 字段不添加索引 -- 1. context_index 字段 添加INDEX(普通索引) ALTER TABLE test_fuzzytext_index ADD INDEX index_name (context_index); -- 2. context_fulltext 字段 添加FULLTEXT(全文索引) ALTER TABLE test_fuzzytext_index ADD FULLTEXT (context_fulltext);最終表結(jié)構(gòu)
Explain - Type 指標(biāo)
訪問(wèn)類(lèi)型,SQL查詢(xún)優(yōu)化中一個(gè)重要指標(biāo),查詢(xún)性能從好到壞依次是
system > const > eqref > ref > fulltext > refornull > indexmerge > uniquesubquery > indexsubquery > range > index > ALL
一般來(lái)說(shuō),好的SQL查詢(xún)至少達(dá)到range級(jí)別,最好能達(dá)到ref。
- system:const連接類(lèi)型的特例,表只有一行記錄(等于系統(tǒng)表,平時(shí)不會(huì)出現(xiàn),可以忽略不計(jì))
- const:表中有且只有一個(gè)匹配行時(shí)使用,對(duì)主鍵或唯一索引的查詢(xún),效率最高,將主鍵置于WHERE列表中,MySQL就能將該查詢(xún)轉(zhuǎn)換為一個(gè)const
- eq_ref:唯一性索引或主鍵查找,對(duì)于每個(gè)索引鍵,表中只有一條記錄與之匹配
- ref:非唯一性索引查找,返回匹配某個(gè)單獨(dú)值的所有行(多行)
- ref_null:類(lèi)似ref類(lèi)型,附加對(duì)NULL值列的查詢(xún)
- index_merge:索引合并優(yōu)化方法(MySQL 5.6以后)
- range:索引范圍掃描,常見(jiàn)于bettween、、in查詢(xún),這種索引列上的范圍掃描比全索引掃描要好。只需要開(kāi)始于某個(gè)點(diǎn),結(jié)束于另一個(gè)點(diǎn),不用掃描全部索引
- index:全表索引掃描,使用索引而非數(shù)據(jù)行掃描
- ALL:全表掃描
index與ALL區(qū)別:index類(lèi)型只遍歷索引樹(shù),索引文件通常比數(shù)據(jù)文件小(Index與ALL雖然都是讀全表,但index是從索引中讀取,而ALL是從硬盤(pán)讀取)。
Explain - Extra 指標(biāo)
- distinct:優(yōu)化distinct操作,在找到第一個(gè)匹配的元組后即停止找同樣值的動(dòng)作
- Not exists:使用not exists優(yōu)化查詢(xún)
- Using filesort:使用額外操作進(jìn)行排序,而不是按照索引進(jìn)行排序,通常出現(xiàn)在
- order by或group by查詢(xún)
- Using index:使用覆蓋索引進(jìn)行查詢(xún),效率高
- Using temporary:使用臨時(shí)表處理查詢(xún),常用于排序、子查詢(xún)、分組查詢(xún)
- Using where:MySQL服務(wù)器層使用WHERE條件過(guò)濾數(shù)據(jù)
- select tables optimized away:直接通過(guò)索引獲得數(shù)據(jù),不用訪問(wèn)表
預(yù)先隨機(jī)插入一些文本數(shù)據(jù)到表中. 使用查詢(xún)語(yǔ)句.
explain select * from test_fuzzytext_index tfi where tfi.context like '%索引%'explain select * from test_fuzzytext_index tfi where tfi.context like '索引%'分析結(jié)果:
%索引% type = ALL Extra = Using where , 結(jié)果集 50+ 耗時(shí)平均 130ms
索引% **type = ALL Extra = Using where , 結(jié)果集 50+ 耗時(shí)平均 130ms
綜上所述: 沒(méi)有索引的字段默認(rèn)全表掃描**
分析結(jié)果:
%索引% type = ALL Extra = Using where , 結(jié)果集 50+ 耗時(shí)平均 130ms
索引% type = renge Extra = Using where , 結(jié)果集 50+ 耗時(shí)平均 125ms
綜上所述: %匹配詞% 全模糊 沒(méi)有使用索引, 右模糊type 為 renge ,
分析結(jié)果:
使用了全文索引后 type = fulltext Extra = Using where; Fthints: noranking, 結(jié)果集 50+ 耗時(shí)平均 59ms
綜上所述: 全文檢索type為 fulltext, 注意目前 MySQL 全文索引只支持根據(jù)空格分詞, 意思是 中文分詞要提前用空格分詞存入, 僅適合數(shù)據(jù)量小的場(chǎng)景. 隨著數(shù)據(jù)增加檢索速度也會(huì)和普通索引拉開(kāi)差距.
總結(jié)一下 %代表一個(gè)或多個(gè)字符的通配符, %關(guān)鍵字% 場(chǎng)景不使用索引, 只會(huì)進(jìn)行全表掃描. 如果有搜索檢索文章內(nèi)容的需求, 可以使用 fulltext 索引 滿足大多數(shù) 搜索場(chǎng)景. MySQL 5.7 支持.
那為什么 %關(guān)鍵字% 不使用索引呢?
在where條件后對(duì)索引字段加了函數(shù)轉(zhuǎn)換或者運(yùn)算邏輯(+、-、*、/、!、<>、%、like'%_'(%放在前面)、or、in (疑問(wèn)、可能存在成本問(wèn)題)、exist等)的處理,比如對(duì)時(shí)間戳字段進(jìn)行日期格式化函數(shù)都會(huì)引起索引失效。
被優(yōu)化器分析后, 發(fā)現(xiàn)走索引還不如不走索引, 效率更高.
- 為什么常見(jiàn)的 B+ 樹(shù)是三層, 可以更多嗎?B+ 樹(shù) 初始化時(shí)只有一層, 會(huì)隨著數(shù)據(jù)擴(kuò)大進(jìn)行樹(shù)的層級(jí)擴(kuò)容, 那么MySQL生產(chǎn)環(huán)境是怎么樣的呢 ?
+ Mysql 數(shù)據(jù)庫(kù)索引的常用種類(lèi)有幾種,每種場(chǎng)景是什么 ?主要有兩種, 一種是 InnoDB 索引, 一種是 替代索引方案.
InnoDB 是 Mysql 5.7 的默認(rèn)索引, 支持現(xiàn)代數(shù)據(jù)庫(kù)理念的一切操作, 比如 事務(wù), 行級(jí)鎖, 數(shù)據(jù)庫(kù)可恢復(fù)性好,默認(rèn)順序索引等...
替代索引方案中, 在一定的特定場(chǎng)景可用, 比如 MyISAM 可以在大量查詢(xún)場(chǎng)景使用. CSV 可以用來(lái)做 數(shù)據(jù)分析, 使用場(chǎng)景有限.
- InnoDB索引方式 與 MyISAM索引方式 的不同點(diǎn) ?
- 三個(gè)外鍵關(guān)聯(lián)表, 怎么寫(xiě) SQL 會(huì)使用索引 ?
使用多列索引并根據(jù)最左匹配原則, 保證表結(jié)構(gòu)設(shè)計(jì)階段主表與關(guān)聯(lián)表之間的關(guān)聯(lián)字段的數(shù)據(jù)類(lèi)型、數(shù)據(jù)長(zhǎng)度、字段的編碼格式以及字段的排序規(guī)則需要保持一致 .
在Mysql建立多列索引(聯(lián)合索引)有最左前綴的原則,即最左優(yōu)先。
如果我們建立了一個(gè)2列的聯(lián)合索引(col1,col2),實(shí)際上已經(jīng)建立了兩個(gè)聯(lián)合索引(col1)、(col1,col2);如果有一個(gè)3列索引(col1,col2,col3),實(shí)際上已經(jīng)建立了三個(gè)聯(lián)合索引(col1)、(col1,col2)、(col1,col2,col3)。
1、b+樹(shù)的數(shù)據(jù)項(xiàng)是復(fù)合的數(shù)據(jù)結(jié)構(gòu),比如(name,age,sex)的時(shí)候,b+樹(shù)是按照從左到右的順序來(lái)建立搜索樹(shù)的,比如當(dāng)(張三,20,F)這樣的數(shù)據(jù)來(lái)檢索的時(shí)候,b+樹(shù)會(huì)優(yōu)先比較name來(lái)確定下一步的所搜方向,如果name相同再依次比較age和sex,最后得到檢索的數(shù)據(jù);但當(dāng)(20,F)這樣的沒(méi)有name的數(shù)據(jù)來(lái)的時(shí)候,b+樹(shù)就不知道第一步該查哪個(gè)節(jié)點(diǎn),因?yàn)榻⑺阉鳂?shù)的時(shí)候name就是第一個(gè)比較因子,必須要先根據(jù)name來(lái)搜索才能知道下一步去哪里查詢(xún)。
2、比如當(dāng)(張三,F)這樣的數(shù)據(jù)來(lái)檢索時(shí),b+樹(shù)可以用name來(lái)指定搜索方向,但下一個(gè)字段age的缺失,所以只能把名字等于張三的數(shù)據(jù)都找到,然后再匹配性別是F的數(shù)據(jù)了, 這個(gè)是非常重要的性質(zhì),即索引的最左匹配特性。(這種情況無(wú)法用到聯(lián)合索引)
- 使用多列索引時(shí),怎么寫(xiě) SQL 會(huì)使用索引?
當(dāng)一張表的查詢(xún)方式比較固定,這時(shí)候可以嘗試創(chuàng)建多列索引,查詢(xún)時(shí)應(yīng)當(dāng)遵從組合索引的規(guī)則,最左原則,查詢(xún)時(shí)使用最頻繁的一列放在最左邊,
例:index(user_id,user_name,user_type)這是一個(gè)組合索引,當(dāng)查詢(xún)時(shí)如果想走索引則 sql:select * from userInfo where user_id='001' and user_name='小張' and user_type='1';-- 這個(gè)時(shí)候是走了索引的,但是select * from userInfo where user_name='小張' and user_type='1';-- 這時(shí)user_id沒(méi)有在where條件內(nèi)將不走索引;-- 此例,user_id字段必須出現(xiàn)在where后面,不然索引將不會(huì)生效。看完不妨問(wèn)問(wèn)自己如何回答這些問(wèn)題, 也可寫(xiě)上在評(píng)論區(qū)留言回答, 溫故知新 ..
關(guān)注我的公眾號(hào) 20K+
深入淺出分享 Java 干貨 , 找回對(duì)代碼的 Passion , 助力月入 20K+
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的无法从套接字读取更多的数据 oracle_小伙面试时被追问数据库优化,面试前如何埋点反杀?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql 缓解竞争热点_MySQL优化
- 下一篇: cnn生成图像显著图_基于CNN与图像前