主頁 > 資料庫 > 【mysql】索引相關的個人總結

【mysql】索引相關的個人總結

2020-09-19 12:09:46 資料庫

重點參考:

  • MySQL索引原理及慢查詢優化 (美團技術分享網站):原理、示例優化都寫的很好,
  • 索引很難么?帶你從頭到尾捋一遍MySQL索引結構,不信你學不會!:原理寫的很好,
  • 【從入門到入土】令人脫發的資料庫底層設計:很詳細的底層原理

一定要仔細看其中講的索引原理!!!本文中都是簡單的總結,

參考:

  • 為什么用了索引,查詢還是慢?

  • MySQL 索引必須了解的幾個重要問題

  • 資料庫中查詢記錄時是否每次只能使用一個索引?

  • 聚簇索引、非聚簇索引、回表:聚簇索引和非聚簇索引講的很詳細,

  • 聚集索引、輔助索引、覆寫索引、聯合索引

  • MySQL索引選擇及規則整理:仔細看里面提到的“前綴索引”

1. 重點知識概括

1.1索引型別

  • Clustered Index(聚簇索引 或 聚集索引)
  • Secondary Index(非聚簇索引 或 輔助索引 或 二級索引,一般指的都是 單列)
  • 聯合索引,多列二級索引
  • 前綴索引,二級索引只截取前N個字符作為索引
  • Covering Index(覆寫索引)

1.2 相關原理

  • B+樹
  • 最左前綴匹配原則
  • 聯合索引的最左前綴匹配原則
  • Index Condition Pushdown (ICP), 索引下推

1.3 使用索引的疑問或總結

2. 索引型別

總體來說,索引型別只存在:聚簇索引 和 非聚簇索引(二級索引),
聯合索引前綴索引都是非聚簇索引中的更明確分類,
覆寫索引(個人覺得)并不算一種索引型別,而是基于非聚簇索引的原理對查詢的一種優化方式,

“回表查詢”:
回到聚簇索引取行資料,1次回表查詢需要2次B+樹的遍歷查找,所以應該盡量避免回表(不要刻意避免,以免得不償失),

2.1 Clustered Index(聚簇索引 或 聚集索引)

  • 鍵值的邏輯順序決定了表中相應行的物理順序
  • 葉子節點中存放了該索引對應的行記錄的完整資料(重點)
  • InnoDB有且只有一個聚簇索引(一般都是PK,MyISAM中都是非聚簇索引)
  • 聚簇索引可以包含多個列(聯合索引),但使用的列越少越好
  1. 為什么InnoDB只有一個聚簇索引,而不將所有索引都使用聚簇索引?
    因為“葉子節點中存放了該索引對應的行記錄的完整資料”,如果所有索引都是聚簇索引,意味著每個葉子節點都保存一份資料,會造成資料的冗余和資源的浪費,

  2. 哪些列索引可以是聚簇索引?
    InnoDB中一般都是PK;
    如果不存在PK,則會選擇唯一非空索引代替,
    如果不存在唯一非空索引,則會隱式定義一個PK來作為聚集索引,

  3. 建議向聚簇索引中插入有序的值
    例如,聚簇索引列是pk,建議選擇int, auto_increment,而避免使用無序的UUID
    a)無序的pk使資料存盤稀疏,這就會出現聚簇索引有可能有比全表掃面更慢
    b)無序的pk新插入資料時,可能需要插入到某些列的中間,這可能導致資料頁分裂,從而移動行資料,
    c)有序的pk值很好的避免了上述無序的pk帶來的問題,

2.2 Secondary Index(非聚簇索引 或 輔助索引 或 二級索引)

(一般都指的是 單列索引,相對 聯合索引 而言)

  • 葉子節點不包含完整的行資料
  • 葉子節點除包含鍵值以外,還包含一個pointer(或者bookmark)用于告訴InnoDB哪里可以找到與索引相對應的行資料(即需要回表查詢,也增加了IO次數)
  • 非聚簇索引 要遠小于 聚簇索引 (mysql基于此特性,會優化一些sql,例如count(*))
  1. 為什么叫二級索引的一種解釋
    二級索引需要兩次B+樹的遍歷查找才能取到資料,
    第一次通過二級索引找到索引的葉子節點,從而找到資料的主鍵(或者其聚簇索引的索引值),然后用該主鍵去聚簇索引中再次通過B+樹查找到完整的行資料,所以,“回表”會有2次B+樹的查找程序,

  2. 為什么輔助索引使用“聚簇索引的索引值”作為pointer,而不是使用"地址值"作為pointer?
    使用"地址值"帶來的好處:
    1)"地址值"比"聚簇索引的索引值"占用更少的空間
    2)減少了1次B+樹查找的程序,
    但是,相應的需要維護輔助索引,這是一個相當困難的維護作業,
    使用“聚簇索引的索引值”作為pointer時,當出現行移動或者資料頁分裂時,輔助索引不受影響(即不需要維護 輔助索引)

  3. 輔助索引中的最左前綴匹配原則
    單列輔助索引遇到<, <=, =, >, >=, between, like(右邊模糊)可以用到索引,
    假設存在索引(col_1),例如liek 'xxx%'是可以用到輔助索引的,

2.3 聯合索引

屬于輔助索引,只是:將多列作為索引,默認多列往右匹配,

  1. 聯合索引中的最左前綴匹配原則
    聯合索引遇到范圍查詢時就停止匹配,(待商榷)
    假設存在索引(a, b, c, d),那么where a =1 and b = 2 and c > 3 and d = 4中,a, b可以用到聯合索引,此時,創建(a, b, d, c)索引更合適,并且由于查詢優化器的優化 where中 a,b,d可以任意順序,
    (擴展疑問:以上聯合索引中,c能否用到索引?參考后面提到的索引下推

  2. 優化器對單列輔助索引聯合索引的選擇
    例如存在單列輔助索引(col_1) 和 聯合索引(col_1, col_2),在執行查詢時,優化器是選擇 單列輔助索引 還是 聯合索引,主要還是需要結合實際SQL,
    where col_1=xxx,可能會選擇 單列輔助索引,(不確定,具體還是看 explain)
    where col_1=xxx order by col_2,選擇 聯合索引,因為col_2是在col_1的基礎上排序,避免了進行1次filesort

2.4 前綴索引

前綴索引能有效減小索引檔案的大小,提高索引的速度,
但是前綴索引也有它的壞處:
1)不能在 ORDER BY 或 GROUP BY 中使用前綴索引
2)也不能把它們用作覆寫索引(Covering Index),

針對2)的個人理解,前綴索引的葉子節點記錄的也只是"主鍵"和"前綴值",需要回表才能拿到完整的值,

例如,假設需要創建 article_title列的索引,但是 article_title 可能很長(索引占用空間多),那么可以只取article_title的前N個字符作為 前綴索引,
語法:CREATE INDEX index_name ON table_name(column_name(length));

2.5 Covering Index(覆寫索引)

InnoDB存盤引擎支持覆寫索引,即從輔助索引中就可以得到查詢的記錄,而不需要查詢聚集索引中的記錄,因此:
1) 使用覆寫索引可以避免回表查詢(減少了大量的IO操作)
例如,假設存在索引(col_1, col_2, col_3),現有查詢SQL select * from table where col_1 = xx,如果在需求滿足的情況下,可以有效利用覆寫索引來優化查詢SQL select col_1, col_2, col_3 from table where col_1 = xx

2) 有助于統計
例如,假設存在非聚簇索引(name)和聚簇索引(id),在執行統計查詢select count(*)時,查詢優化器可能會選擇使用 非聚簇索引,因為,非聚簇索引 要遠小于 聚簇索引,

暫時還無法理解2),特別是 聚集索引、輔助索引、覆寫索引、聯合索引 中基于 聯合索引 & count 的示例更不理解~~~

student表:PRIMARY KEY (id), KEY idx_name (name), KEY idx_school_age (school,age)`

執行sql:select count(*) from student
優化器會選用 idx_name 這個輔助索引,(具體看 explain)

執行SQL:select count(*) from student where age > 10 and age < 15
優化器會選用 idx_school_age 這個輔助索引,(具體看 explain)

3. 索引中的原理

3.1 B+樹

  • MySQL索引原理及慢查詢優化 (美團技術分享網站):原理、示例優化都寫的很好,
  • 索引很難么?帶你從頭到尾捋一遍MySQL索引結構,不信你學不會!:原理寫的很好,
  • 【從入門到入土】令人脫發的資料庫底層設計:很詳細的底層原理
    再次,再次,再次通過這3篇大神的文章簡單理解就好,如果想深入理解,再baidu/google,

3.2 (單列輔助索引的)最左前綴匹配原則

忽略,

3.3 聯合索引的最左前綴匹配原則

相比單例輔助索引的最左前綴匹配原則,聯合索引 是從左往右依次比較列,
例如col_1, col_2, col_3, col_4,先比較col_1,再比較col_2,以此類推,

3.4 Index Condition Pushdown (ICP), 索引下推

參考:

  • 索引下推(5.6版本+)
  • MySQL--索引條件下推優化
  • mysql索引篇之覆寫索引、聯合索引、索引下推

在前面提到了一個疑問:
where a = 1 and b = 2 and c > 3 and d = 4在已有聯合索引(a, b, c, d)時,c/d能否用到聯合索引?

在主要閱讀的的2篇文章(美團大佬、java知音)都說的是:

最左前綴匹配原則,mysql會一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配,
比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的
如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調整,

其中并未提到c,而且個人覺得 c&d 都可以用到索引(只是不知道其性能如何),
針對這疑問,我看到了索引下推

例如以上SQL可能有2種執行可能:
1)假設 c&d 都沒用到索引,根據聯合索引查詢到滿足 a&b 的條件,然后就回表找到所有行資料,再進行遍歷篩選出c > 3 and d = 4的資料行,

2)假設 c&d 都用到了索引,那么最后回表的資料行 一定小于等于 1)中回表的資料行,這就是mysql的索引下推

mysql默認啟用索引下推,可以通過變數來修改:
SET optimizer_switch = 'index_condition_pushdown=off';

注意:
a) 索引下推只能用于二級索引,(聚簇索引包含了行資料,這時候索引下推并不會起到減少回表操作的效果)
b) 索引下推一般可用于所求查詢欄位(select列)不是/不全是聯合索引的欄位,查詢條件為多條件查詢且查詢條件子句(where/order by)欄位全是聯合索引,(沒理解~~)

備注:
個人并不確定是 c&d 都用到索引,還是只有 c 用到索引,d未用到索引,

4. 索引使用中的疑問總結

(ps: cnblog的markdown對于 1.-的決議貌似有錯誤,導致下面的序號是亂的)

  1. 索引不一定能提高查詢速度,甚至可能比不存在索引時更慢!

  2. 一次查詢只能用到1個索引
    如果多列查詢存在多個索引,查詢優化器一般選擇區分度高的索引列,

  3. 區分度,簡單公式:count(distinct col) / count(*),
    意味著通過索引列可以回傳更少的rows(回表查詢的行數更少)
    具體需要看實際資料,比如假設is_download只存在true/false,當下載完成后將false改為true,
    此時實際業務資料是很少存在false,當存在大量查詢false的時候,可以創建索引,

  4. 覆寫索引擁有更高效率和性能

  5. 無法使用索引的情況

  • <>, !=, not in
  • 對欄位進行函式運算
  • 索引欄位存在null
  • 字串不加單引號,例如phone是varchar型別但sql是where phone=13800010002
  1. 創建索引的原則
  • 最左前綴匹配原則
  • 區分度高的列(美團文章提到)一般需要join的欄位都要求是0.1以上,
  • 盡量的擴展索引,不要新建索引,
    聯合索引 & 最左前綴匹配原則的優化,當存在(col_a, col_b)的聯合索引后,大多情況下不需要再創建a索引
  • 例如書 “SQL Tuning“,如果選擇性超過 20% 那么全表掃描比使用索引性能更優,
  1. 基于 新增/修改索引 來優化查詢時,不能只看到當前需要優化的SQL,還需要結合該表的其余查詢SQL來綜合分析,
    例如,當前待優化sql創建了聯合索引(col_1, col_2, col_3, col_4),但是可能另外一條sql可能需要聯合索引(col_1, col_2, col_4),所以,最終聯合索引(col_1, col_2, col_4, col_3)更適合,

  2. 聯合索引,如何決定其col的順序?
    最左前匹配原則&列的區分度 的理解運用,當然還要結合實際SQL,

  3. 范圍查詢是否會使用索引(例如 like、between-and、in)?
    可以使用到索引(但具體還是要看寫法),

  4. 性別欄位是否需要創建索引(十萬級以上的表,只有男/女)?
    為什么重復值高的欄位不能建索引
    mysql千萬級大表,關于性別及年齡欄位是否需要加索引?
    沒有絕對,要根據實際的資料,
    例如1億的資料,其中只有10萬的"男"資料,并且總是查詢少的那部分資料,那么存在索引的效果更好,

(ps:整理完一看,并沒有寫或整理出多少東西...但磨磨唧唧也花費了蠻多時間)

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/81206.html

標籤:MySQL

上一篇:MySQL基礎

下一篇:[MySQL]mysql binlog回滾資料

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more