進行後端開發經常會與資料庫打交道,對於資料庫的一些核心基礎了解太淺,比如經常聽到的資料庫索引、鎖等,在小專案開發過程中也沒有過於嚴格的執行索引的建立,而是想當然的對錶直接設定乙個自增字段作為主鍵,這些還是源於對於索引的認識不夠深喃。
在此之前,對於索引的認識如下:
索引相當於一張表的附加表,儲存著表中建立索引的字段值以及對應記錄值的位址,在進行查詢操作時,首先在索引表中進行查詢,根據查詢的條件找到相關記錄的位址,再根據記錄位址在表中訪問對應的記錄。
經常進行insert、update、delete操作就不要建立索引了,換言之,索引會降低插入、刪除、更新等維護任務的速度。
索引分為聚集索引和非聚集索引。
目前mysql的innodb引擎支援hash索引、b+樹索引和全文索引。
索引的最左匹配原則。
只停留在了解階段是遠遠不夠的,必須深入了解其中的每乙個細節才能更好的掌握索引的奧秘,比如為什麼索引會降低插入、刪除等維護的速度、hash索引和b+樹索引的區別以及為什麼索引會加快查詢的速度等等。
mysql的資料儲存是基於頁的方式
各個資料頁之間以雙向鍊錶的形式連線,在資料頁內部各個資料之間也已單向鍊錶的形式存在。
每個資料頁會為儲存在它裡面的資料生成乙個頁目錄,在通過主鍵查詢時可以通過二分法在頁目錄中快速定位到對應的槽位置,再通過遍歷該槽對應分組中的記錄即可快速找到指定的資料。
對於非主鍵的字段作為查詢條件,只能從最小記錄開始遍歷。
如果我們用這樣一條未經優化的查詢語句:select * from table_name where name='zhang'
,它的查詢步驟如下:
定位到對應頁。需要遍歷雙向鍊錶,找到所在的頁。
在所在頁中找到相應的資料。由於沒有新增索引,只有遍歷頁中的單向鍊錶了。
可想而知,當資料量相當龐大時,遍歷單向鍊錶是多麼的花費時間的事。
索引無非就是將無序的資料變成相對有序的。
以下是要找到id為8的記錄簡要步驟:
通過頁目錄可以在o(logn)的時間內快速定位到資料具體的頁上,如果沒有用索引的話,就需要遍歷整個雙向鍊錶以及單向鍊錶來找到具體的資料。
mysql索引的底層實現是b+樹,在葉子節點上儲存資料,其他節點只是作為乙個索引的作用。
首先知道了mysql底層是b+樹的結構。
為了更好的保持b+樹的結構性,在每次進行insert、update和delete後都需要維護樹結構,這些維護工作也將導致額外的開銷,導致索引降低了增刪改的速度。
雜湊索引即採用雜湊演算法,將鍵換算成雜湊值,檢索時不需要像b+樹那樣遍歷節點,只需要一次雜湊演算法即可立即定位到相應的位置,速度極快。
雖然如此,但是雜湊演算法也有它的侷限性。
雜湊索引沒法利用索引完成排序、不支援最左匹配原則、在存在大量重複鍵的情況下會有雜湊碰撞問題、不支援範圍查詢。
mysql的innodb引擎支援雜湊索引,但是是一種自適應雜湊,innodb儲存引擎會根據表的使用情況自動為表生成雜湊索引,不能人為干預是否在一張表中生成雜湊索引。
聚集索引:按照每張表的主鍵構造一棵b+樹。
非聚集索引:以非主鍵建立的索引。
聚集索引在葉子節點儲存的是表中的資料,並且聚集索引在邏輯上是連續的,而非聚集索引在葉子節點儲存的是主鍵和索引列。當使用非聚集索引查詢時,拿到葉子上的主鍵再去查詢想要的資料。
聚集索引在一張表中只能有乙個,而非聚集索引可以有多個。
說到非聚集索引就需要說到覆蓋索引。非聚集索引查詢需要在葉子節點拿到主鍵,再通過主鍵回表拿到具體的資料。而覆蓋索引就是當要查詢的列就是索引時,拿到主鍵後就不需要回表操作了。
例子:建立了索引(username,age),在查詢資料時:select username,age from user where username='zhang' and age=21
以上這條查詢條件是會走索引的,並且要查詢的列已經在葉子節點上了,符合覆蓋節點,於是不需要再拿到對應的主鍵回表了。
索引可以是乙個列(a),也可以是多個列共同聯合構成(a,b,c,d),即聯合索引。
索引只能匹配鍵值相等的情況,不知道範圍查詢,即遇到like、between、>、《時就不能進行匹配,後續匹配過程會退化成線性查詢。列的排列順序也將決定可命中索引的次數。
如果有索引(a、b、c、d),查詢條件是a=1 and b=2 and c>3 and d=4
則會在每個節點依次命中a、b、c,無法命中d。(索引無法範圍匹配)
對於in
以及=
等的順序,mysql會自動優化這些條件的順序,以匹配更多的索引列。
例子:如有索引(a, b, c, d),查詢條件c > 3 and b = 2 and a = 1 and d < 4與a = 1 and c > 3 and b = 2 and d < 4等順序都是可以的,mysql會自動優化為a = 1 and b = 2 and c > 3 and d < 4,依次命中a、b、c。
索引的最左匹配原則就是對於查詢條件會一直向右匹配直到遇到範圍匹配或匹配條件結束。
資料庫索引到底是什麼,是怎樣工作的?
我們通過乙個簡單的例子來開始教程,解釋為什麼我們需要資料庫索引。假設我們有乙個資料庫表 employee,這個表有三個字段 列 分別是 employee name employee age 和employee address。假設表employee 有上千行資料。現在假設我們要從這個表中查詢出所有名...
資料庫索引到底是什麼,是怎樣工作的?
索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。資料庫索引好比是一本書前面的目錄,能加快資料庫的查詢速度。例如這樣乙個查詢 select from table1 where id 44。如果沒有索引,必須遍歷整個表,直到id等於44的這一行被找到為止 有了...
資料庫索引到底是什麼,是怎樣工作的?
資料庫索引到底是什麼,是怎樣工作的?我們通過乙個簡單的例子來開始教程,解釋為什麼我們需要資料庫索引。假設我們有乙個資料庫表 employee,這個表有三個字段 列 分別是 employee name employee age 和employee address。假設表employee 有上千行資料。...