2.mysql索引
3.小結
要深入理解mysql的索引知識,那就首先也是必須要先完全理解關於「樹」這種資料結構,要不然我們就是看一百遍文章也不明白所以然。所以,如果你還沒有完全理解「樹」,那麼就請先看之前的三篇部落格:
[《(一)樹(樹、二叉樹、滿二叉樹、完全二叉樹、二叉搜尋樹、二叉平衡樹、b-tree、b+tree)》]
《漫畫:什麼是b-樹?》
《漫畫:什麼是b+樹?》
那麼要理解到什麼程度呢?
必須要先完全理解關於「樹」這種資料結構
必須要先完全理解關於「樹」這種資料結構
必須要先完全理解關於「樹」這種資料結構
必須要先完全理解關於「樹」這種資料結構
重要的事情說3遍,這裡我說四遍。
我們來下面這張圖,這就是mysql資料庫的基本構成及sql(查詢)語句的執行過程。我們根據這個圖,簡要的說一下這個過程:
基本上,mysql是由server層和儲存引擎兩部分組成。
server層:主要包括聯結器、查詢快取、分析器、優化器、執行器等,包含了mysql 的大多數核心服務功能,如內建函式、自定義函式、儲存過程、觸發器、檢視等;
儲存引擎:主要作用是負責資料的儲存和讀取,主要包括innodb、myisam、ndb、memory 、infobright 、blackhole等儲存引擎。從mysql 5.5.8 版本開始是預設的儲存引擎是innodb,之前的版本預設的儲存引擎是myisam。關於各種儲存引擎,我們不再進行詳細的介紹,我們這篇文章主要是基於innodb,這也是我們最常用的乙個innodb。
索引是為了加速對錶中資料行的檢索而建立的一種分散的儲存結構。索引是針對表而建立的,它是由資料頁面以外的索引頁面組成的,每個索引頁面中的行都會含有邏輯指標,以便加速檢索物理資料。索引的出現其實就是為了提高資料查詢的效率,就像書的目錄一樣。
與其說是索引的比較,其實我認為不如說是幾種資料結構的比較。我們這裡先說三個比較常見的索引模型:雜湊表、有序陣列、二叉搜尋樹、二叉平衡樹、b-tree和b+tree,來進一步推理出mysql所使用的索引模型(資料結構)。我們以乙個簡單的學生(s)表為例來說明:
id(學生id)
name(姓名)
1jane
2jack
3john
4bill
5blake
6bob
雜湊表是一種以鍵 - 值(key-value)儲存資料的結構,可以通過key直接獲取到value值,它的維護乙個陣列,把key經過hash之後,確定當前key所在陣列的位置,然後把value放在陣列這個位置。當不同的key經過hash計算後重複時,這時候在這個位置直接拉出乙個鍊錶,來儲存各個value。如下圖所示:
從圖中我們可以看出,要根據id查詢出name,速度是非常快的,但是如果我想查詢處在[3,6]這個區間中的學生姓名,那就必須要進行全表掃瞄了,此時的io次數就會過多,嚴重影響了查詢的效率(因為id在上面圖中並不是有序的,即hash之後的值並不是按照id的真實順序排列,並且hash的值越分散越好,減少後面的鍊錶元素的數量)。即:雜湊表這種結構適用於只有等值查詢的場景,比如 memcached
說明:這裡說的無序並不是說id進行hash之後的值在陣列中無序,hash值在陣列中肯定是有序的,而是說陣列中hash值的順序並不是源id的順序,即對映到id,那就是無序的。好,既然因為它是無序的,我們就採用有序的,自然就會想到有序陣列,那麼有序陣列可以不可以?我們往下看。
有序陣列沒有什麼好說的,我們都清楚的很,平時寫**用的也是最多的一種資料結果。它查詢快(即:隨機訪問效率很高,時間複雜度可以達到o(1),因為陣列的記憶體是連續的,想要訪問那個元素,直接從陣列的首位址向後偏移就可以訪問到了),即便不是放在一塊連續的記憶體中,只要保證是有序的,那我們也可以使用二分法來比較快速的找到,時間複雜度也就在o(log(n)),也並不是不可以接受。那麼看似這種結構比較完美了,其實不然,它最大的問題就在於更新和刪除的時候,要進行元素的挪動,新增的時候還會涉及到擴容,代價就太高了,即有序陣列索引只適用於靜態儲存引擎
我們只用了乙個三階b-tree,樹的高度就降低了,試想一下,我們我們擴大階數,是不是就能更進一步降低我們樹的高度,從而更進一步降低io的次數,提高查詢的效率。樹相對於平衡二叉樹的不同是,每個節點包含的關鍵字增多了,特別是在b樹應用到資料庫中的時候,資料庫充分利用了磁碟塊的原理(磁碟資料儲存是採用塊的形式儲存的,每個塊的大小為4k,每次io進行資料讀取時,同乙個磁碟塊的資料可以一次性讀取出來)把節點大小限制為能充分使用在磁碟塊大小範圍;把樹的節點關鍵字增多後樹的層級比原來的二叉樹少了,減少資料查詢的次數和複雜度。看似幾乎完美,但我們知道,mysql並沒有採用b-tree作為它的底層資料結構(我們可以想到最簡單的原因,如果乙個查詢無法命中索引,那就要進行全表掃瞄,那麼這個開銷可就大了,它需要對樹進行多次的查詢),而是採用了它的改進版本b+tree,這個資料結構我們在之前也做了介紹,下面我們就看一下b+tree到底行不行?行的話,行在**?
和b-tree相比,b+tree做了一些改進,使得它更適合做mysql資料庫的索引,主要體現在以下幾個方面:
從根上理解MySQL 第二章
mysql.server也是乙個啟動指令碼,它會間接的呼叫mysqld safe,在呼叫mysql.server時在後邊指定start引數就可以啟動伺服器程式了 localhost 127.0.0.1和0.0.0.0和本機ip的區別 localhost localhost其實是網域名稱,一般wind...
mysql索引學習(一)
mysql官方對索引的定義為 索引 index 是幫助mysql高效獲取資料的資料結構。提取句子主幹,就可以得到索引的本質 索引是一種資料結構。資料庫查詢是資料庫的主要功能之一,最基本的查詢演算法是順序查詢 linear search 時間複雜度為o n 顯然在資料量很大時效率很低。優化的查詢演算法...
從留言簿開始,學習MonoRail MVC 一
關注mvc開發web應用程式是看到 乙個.net的mvc web框架 這篇文章以後開始的,通過官方 的幾個教程很快引起了我的興趣,的確是非常簡潔,讓我想起了asp的時代。再搜尋了一下asp.net mvc框架,發現monorail相對來說文件較多一些,決定從它開始。最近一段時間微軟要推出asp.ne...