索引最全分析

2021-10-05 06:57:51 字數 3458 閱讀 1380

普通索引(由關鍵字key或index定義的索引)的唯一任務是加快對資料的訪問速度。

查詢時,遇到第乙個不符合條件的才返回。

更新時,找到位置直接更新。

如果他是乙個普通索引我們現在去查詢,當查詢到符合的資料的時候這個時候他就會在進行第二次查詢,因為列裡面的資料是唯一的

所以第二次查詢肯定是沒有資料的,這一次查詢通過二分法去查詢b+樹查詢到二叉樹的葉子結點,每個葉子結點都會對應乙個資料塊(資料頁),如果這個資料頁在記憶體中那麼他也就不用去在磁碟或硬碟去讀區這個資料了,直接在記憶體中讀取

我們也知道乙個資料塊大概是可以儲存幾千條資料的,所以在第一次查詢的時候剛好這個資料塊的尾部,在進行第二次查詢的時候就要在進行io讀取了 一次io讀取是很低效的。

如果是唯一索引的話這樣的話就不會再進行第二次讀取了,所以在最壞的情況下,普通索引和唯一索引的最大區別是多進行一次io讀取,概率極小

當需要更新乙個資料頁時,如果資料頁在記憶體中就直接更新,而如果這個資料頁還沒有在記憶體中的話,在不影響資料一致性的前提下,inoodb會將這些更新操作快取在change buffer中,這樣就不需要從磁碟中讀入這個資料頁了。在下次查詢需要訪問這個資料頁的時候,將資料頁讀入記憶體,然後執行change buffer中與這個頁有關的操作。通過這種方式就能保證這個資料邏輯的正確性。

需要說明的是,雖然名字叫作change buffer,實際上它是可以持久化的資料。也就是說,change buffer在記憶體中有拷貝,也會被寫入到磁碟上。

將change buffer中的操作應用到原資料頁,得到最新結果的過程稱為merge。除了訪問這個資料頁會觸發merge外,系統有後台執行緒會定期merge。在資料庫正常關閉(shutdown)的過程中,也會執行merge操作。

如果能夠將更新操作先記錄在change buffer,減少讀磁碟,語句的執行速度會得到明顯的提公升。而且,資料讀入記憶體是需要占用buffer pool的,所以這種方式還能夠避免占用記憶體,提高記憶體利用率。

(在redlog裡面也會存乙份,也會儲存changebuffer的才運算元據,es(elaticsearch)的一種同步方式是通過redo log 來進行是實時同步的)

什麼情況可以使用changebuffer?

對於唯一索引來說,所有的更新操作都要先判斷這個操作是否違反唯一性約束。

比如,要插入(1,100)這個記錄,就要先判斷現在表中是否已經存在n=1的記錄,而這必須要將資料頁讀入記憶體才能判斷。如果都已經讀入到記憶體了,那直接更新記憶體會更快,就沒必要使用change buffer了。

因此,唯一索引的更新就不能使用change buffer,實際上也只有普通索引可以使用。

當唯一索引進行更新操作的時候 會先進行一次查詢是否唯一,再進行和普通索引一樣的操作。

所以在符合業務邏輯和無誤的前提下:唯一索引比普通索引多乙個查詢操作。(在進行insert的時候會根據主鍵來進行查住 主鍵索引的資料結構發生改變)

多用普通索引,少用唯一索引

還有就是change buffer的使用 在更新讀取少的 情況下放大change buffer的儲存量

因為chanbuffer量越大其變更的數量更多 減少的io次書更多,效能也就提高了。

第一種情況是,這個記錄要更新的目標頁在記憶體中。這時,innodb的處理流程如下:

對於唯一索引來說,找到1和3之間的位置,判斷到沒有衝突,插入這個值,語句執行結束;

對於普通索引來說,找到1和3之間的位置,插入這個值,語句執行結束。

這樣看來,普通索引和唯一索引對更新語句效能影響的差別,只是乙個判斷,只會耗費微小的cpu時間。

第二種情況是,這個記錄要更新的目標頁不在記憶體中。這時,innodb的處理流程如下:

對於唯一索引來說,需要將資料頁讀入記憶體,判斷到沒有衝突,插入這個值,語句執行結束;

對於普通索引來說,則是將更新記錄在change buffer,語句執行就結束了。

userid 、 mobile兩個單例索引

當使用userid or mobile,兩個索引都生效;

當使用userid and mobile,只有userid是生效索引

這種建議使用組合索引

組合索引,對於(1,2,3),只有,123,12,13,有效並用and連線,用or都無效

文字欄位上的普通索引只能加快對出現在字段內容最前面的字串(也就是字段內容開頭的字元)進行檢索操作。

如果欄位裡存放的是由幾個、甚至是多個單詞構成的較大段文字,普通索引就沒什麼作用了。

這種檢索往往以like %word%的形式出現,這對mysql來說很複雜,如果需要處理的資料量很大,響應時間就會很長。

這時候用全文索引

只有欄位的資料型別為 char、varchar、text 及其系列才可以建全文索引。

mysql 5.6 及以後的版本,innodb 儲存引擎才支援全文索引;

fulltext key content_tag_fulltext(content,tag)  // 建立聯合全文索引列
使用全文索引

和常用的模糊匹配使用 like + % 不同,全文索引有自己的語法格式,使用 match 和 against 關鍵字,比如

select * from fulltext_test 

where match(content,tag) against('*** ***');

注意:

match() 函式中指定的列必須和全文索引中指定的列完全相同,否則就會報錯,無法使用全文索引,這是因為全文索引不會記錄關鍵字來自哪一列。

如果想要對某一列使用全文索引,請單獨為該列建立全文索引。

兩種全文索引

1、上面的叫自然語言全文索引

2、布林全文索引

在布林搜尋中,我們可以在查詢中自定義某個被搜尋的詞語的相關性,當編寫乙個布林搜尋查詢時,可以通過一些字首修飾符來定製搜尋。

提高該詞的相關性,查詢的結果靠前 < 降低該詞的相關性,查詢的結果靠後 (*)星號 萬用字元,只能接在詞後面 對於上面提到的問題,可以使用布林全文索引查詢來解決,使用下面的命令,a、aa、aaa、aaaa 就都被查詢出來了。

select * test where match(content) against('a*' in boolean mode);
還有主鍵索引,外來鍵索引,比較常用不做介紹

最全的HTTP頭部資訊分析

http 頭部解釋 21.server web 伺服器表明自己是什麼軟體及版本等資訊。例如 server apache 2.0.61 unix 22.user agent 瀏覽器表明自己的身份 是哪種瀏覽器 例如 user agent mozilla 5.0 windows u windows nt...

最全的HTTP頭部資訊分析

http 頭部解釋 content encoding 一種介質型別修飾符,標明乙個實體是如何編碼的。例如 content encoding zipcontent language 用於指定在輸入流中資料的自然語言型別。例如 content language en content length 指定包...

索引和索引例項分析

資料庫索引,是資料庫管理系統中乙個排序的資料結構,以協助快速查詢 更新資料庫表中資料。就像我們以前用的新華字典的目錄一樣,能幫助我們快速查詢到某乙個字。分類角度 索引名稱 資料結構 b 樹,hash索引,r tree等 儲存層面 聚簇索引,非聚簇索引 邏輯層面 主鍵索引,普通索引,復合索引,唯一索引...