1. 程式人生 > >MySQL效能調優——索引詳解與索引的優化

MySQL效能調優——索引詳解與索引的優化

——索引優化,可以說是資料庫相關優化、理解尤其是查詢優化中最常用的優化手段之一。所以,只有深入索引的實現原理、儲存方式、不同索引間區別,才能設計或使用最優的索引,最大幅度的提升查詢效率!

一、BTree索引

1、概述

Mysql資料庫中使用最頻繁的索引型別,基本所有儲存引擎都支援BTree索引。正是其優異的檢索表現,才使其有這樣的地位。

2、儲存結構

正如其名,這類索引的物理檔案大多就是以BTree結構來儲存的,但會有不同的儲存引擎在使用BTree索引時,對儲存結構稍作修改,比如MyISAM儲存引擎,使用B+Tree的資料結構,它相對與BTree結構,所有的資料都存放在葉子節點上,且把葉子節點通過指標連線到一起,形成了一條資料鏈表,以加快相鄰資料的檢索效率。

另外,對於innoDB儲存引擎,雖然同樣使用B+Tree作為索引的儲存結構,但具體實現卻與MyISAM截然不同,這也是作為MyISAM與InnoDB儲存引擎的一個重要區別反覆被面試官問到。(關於MyISAM與InnoDB儲存引擎可參看部落格MySQL架構設計——MyISAM儲存引擎與InnoDB儲存引擎

(1)MyISAM引擎索引結構的葉子節點的資料域,存放的並不是實際的資料記錄,而是資料記錄的地址。索引檔案與資料檔案分離,這樣的索引稱為“非聚簇索引”。MyISAM的主索引與輔助索引區別並不大,只是主鍵索引不能有重複的關鍵字。

如下圖所示為非聚簇索引的主鍵索引:


其檢索演算法:先按照B+Tree的檢索演算法檢索,找到指定關鍵字,則取出對應資料域的值,作為地址取出資料記錄。


(2)InnoDB引擎索引結構的葉子節點的資料域,存放的就是實際的資料記錄(對於主索引,此處會存放表中所有的資料記錄;對於輔助索引此處會引用主鍵,檢索的時候通過主鍵到主鍵索引中找到對應資料行),或者說,InnoDB的資料檔案本身就是主鍵索引檔案,這樣的索引被稱為“聚簇索引”,一個表只能有一個聚簇索引。

如下圖所示為聚簇索引的主鍵索引:


二、Hash索引

1、概述及儲存結構

主要就是通過Hash演算法(常見的Hash演算法有直接定址法、平方取中法、摺疊法、除數取餘法、隨機數法),將資料庫欄位資料轉換成定長的Hash值,與這條資料的行指標一併存入Hash表的對應位置;如果發生Hash碰撞(兩個不同關鍵字的Hash值相同),則在對應Hash鍵下以連結串列形式儲存。

檢索演算法:在檢索查詢時,就再次對待查關鍵字再次執行相同的Hash演算法,得到Hash值,到對應Hash表對應位置取出資料即可,如果發生Hash碰撞,則需要在取值時進行篩選。目前使用Hash索引的資料庫並不多,主要有Memory等。

2、Hash索引的弊端

一般來說,索引的檢索效率非常高,可以一次定位,不像B-Tree索引需要進行從根節點到葉節點的多次IO操作。有利必有弊,Hash演算法在索引的應用也有很多弊端。

a、Hash索引僅僅能滿足等值的查詢,範圍查詢不保證結果正確。因為資料在經過Hash演算法後,其大小關係就可能發生變化。

b、Hash索引不能被排序。同樣是因為資料經過Hash演算法後,大小關係就可能發生變化,排序是沒有意義的。

c、Hash索引不能避免表資料的掃描。因為發生Hash碰撞時,僅僅比較Hash值是不夠的,需要比較實際的值以判定是否符合要求。

d、Hash索引在發生大量Hash值相同的情況時效能不一定比B-Tree索引高。因為碰撞情況會導致多次的表資料的掃描,造成整體效能的低下,可以通過採用合適的Hash演算法一定程度解決這個問題。

e、Hash索引不能使用部分索引鍵查詢。因為當使用組合索引情況時,是把多個數據庫列資料合併後再計算Hash值,所以對單獨列資料計算Hash值是沒有意義的。

三、Full-Text索引

1、概述

全文索引,目前MySQL中只有MyISAM儲存引擎支援,並且只有CHAR、VARCHAR、TEXT型別支援。它用於替代效率較低的LIKE模糊匹配操作,而且可以通過多欄位組合的全文索引一次性全模糊匹配多個欄位。

2、儲存結構

同樣使用B-Tree存放索引資料,但使用的是特定的演算法,將欄位資料分割後再進行索引(一般每4個位元組一次分割),索引檔案儲存的是分割前的索引字串集合,與分割後的索引資訊,對應Btree結構的節點儲存的是分割後的詞資訊以及它在分割前的索引字串集合中的位置。

四、索引利弊

1、索引的好處

a、提高資料檢索的效率,降低檢索過程中必須要讀取得資料量,降低資料庫IO成本。

b、降低資料庫的排序成本。因為索引就是對欄位資料進行排序後儲存的,如果待排序的欄位與索引鍵欄位一致,就在取出資料後不用再次排序了,因為通過索引取得的資料已滿足排序要求。另外,分組操作是先排序後分組,所以索引同樣可以省略分組的排序操作,降低記憶體與CPU資源的消耗。

2、索引的弊端

a、索引會增加 增、刪、改操作所帶來的IO量與調整索引的計算量。

b、索引要佔用空間,隨著資料量的不斷增大,索引還會帶來儲存空間的消耗。

五、判斷是否應該建索引的條件

1、較頻繁的作為查詢條件的欄位應該建立索引

2、唯一性太差的欄位不適合單獨建立索引,即使頻繁作為查詢條件

3、增、刪、改操作較多的資料庫欄位不適合建索引

附:計算機記憶體存取、磁碟存取原理(轉載自:張洋的部落格園http://www.uml.org.cn/sjjm/201107145.asp)

主存存取原理

目前計算機使用的主存基本都是隨機讀寫儲存器(RAM),現代RAM的結構和存取原理比較複雜,這裡本文拋卻具體差別,抽象出一個十分簡單的存取模型來說明RAM的工作原理。

image

圖1

從抽象角度看,主存是一系列的儲存單元組成的矩陣,每個儲存單元儲存固定大小的資料。每個儲存單元有唯一的地址,現代主存的編址規則比較複雜,這裡將其簡化成一個二維地址:通過一個行地址和一個列地址可以唯一定位到一個儲存單元。圖5展示了一個4 x 4的主存模型。

主存的存取過程如下:

當系統需要讀取主存時,則將地址訊號放到地址總線上傳給主存,主存讀到地址訊號後,解析訊號並定位到指定儲存單元,然後將此儲存單元資料放到資料匯流排上,供其它部件讀取。

寫主存的過程類似,系統將要寫入單元地址和資料分別放在地址匯流排和資料匯流排上,主存讀取兩個匯流排的內容,做相應的寫操作。

這裡可以看出,主存存取的時間僅與存取次數呈線性關係,因為不存在機械操作,兩次存取的資料的“距離”不會對時間有任何影響,例如,先取A0再取A1和先取A0再取D3的時間消耗是一樣的。

磁碟存取原理

上文說過,索引一般以檔案形式儲存在磁碟上,索引檢索需要磁碟I/O操作。與主存不同,磁碟I/O存在機械運動耗費,因此磁碟I/O的時間消耗是巨大的。

圖6是磁碟的整體結構示意圖。

image

圖2

一個磁碟由大小相同且同軸的圓形碟片組成,磁碟可以轉動(各個磁碟必須同步轉動)。在磁碟的一側有磁頭支架,磁頭支架固定了一組磁頭,每個磁頭負責存取一個磁碟的內容。磁頭不能轉動,但是可以沿磁碟半徑方向運動(實際是斜切向運動),每個磁頭同一時刻也必須是同軸的,即從正上方向下看,所有磁頭任何時候都是重疊的(不過目前已經有多磁頭獨立技術,可不受此限制)。

圖7是磁碟結構的示意圖。

image

圖3

碟片被劃分成一系列同心環,圓心是碟片中心,每個同心環叫做一個磁軌,所有半徑相同的磁軌組成一個柱面。磁軌被沿半徑線劃分成一個個小的段,每個段叫做一個扇區,每個扇區是磁碟的最小儲存單元。為了簡單起見,我們下面假設磁碟只有一個碟片和一個磁頭。

當需要從磁碟讀取資料時,系統會將資料邏輯地址傳給磁碟,磁碟的控制電路按照定址邏輯將邏輯地址翻譯成實體地址,即確定要讀的資料在哪個磁軌,哪個扇區。為了讀取這個扇區的資料,需要將磁頭放到這個扇區上方,為了實現這一點,磁頭需要移動對準相應磁軌,這個過程叫做尋道,所耗費時間叫做尋道時間,然後磁碟旋轉將目標扇區旋轉到磁頭下,這個過程耗費的時間叫做旋轉時間。

區域性性原理與磁碟預讀

由於儲存介質的特性,磁碟本身存取就比主存慢很多,再加上機械運動耗費,磁碟的存取速度往往是主存的幾百分分之一,因此為了提高效率,要儘量減少磁碟I/O。為了達到這個目的,磁碟往往不是嚴格按需讀取,而是每次都會預讀,即使只需要一個位元組,磁碟也會從這個位置開始,順序向後讀取一定長度的資料放入記憶體。這樣做的理論依據是電腦科學中著名的區域性性原理:

當一個數據被用到時,其附近的資料也通常會馬上被使用。

程式執行期間所需要的資料通常比較集中。

由於磁碟順序讀取的效率很高(不需要尋道時間,只需很少的旋轉時間),因此對於具有區域性性的程式來說,預讀可以提高I/O效率。

預讀的長度一般為頁(page)的整倍數。頁是計算機管理儲存器的邏輯塊,硬體及作業系統往往將主存和磁碟儲存區分割為連續的大小相等的塊,每個儲存塊稱為一頁(在許多作業系統中,頁得大小通常為4k),主存和磁碟以頁為單位交換資料。當程式要讀取的資料不在主存中時,會觸發一個缺頁異常,此時系統會向磁碟發出讀盤訊號,磁碟會找到資料的起始位置並向後連續讀取一頁或幾頁載入記憶體中,然後異常返回,程式繼續執行。

B-/+Tree索引的效能分析

到這裡終於可以分析B-/+Tree索引的效能了。

上文說過一般使用磁碟I/O次數評價索引結構的優劣。先從B-Tree分析,根據B-Tree的定義,可知檢索一次最多需要訪問h個節點。資料庫系統的設計者巧妙利用了磁碟預讀原理,將一個節點的大小設為等於一個頁,這樣每個節點只需要一次I/O就可以完全載入。為了達到這個目的,在實際實現B-Tree還需要使用如下技巧:

每次新建節點時,直接申請一個頁的空間,這樣就保證一個節點物理上也儲存在一個頁裡,加之計算機儲存分配都是按頁對齊的,就實現了一個node只需一次I/O。

B-Tree中一次檢索最多需要h-1次I/O(根節點常駐記憶體),漸進複雜度為O(h)=O(logdN)。一般實際應用中,出度d是非常大的數字,通常超過100,因此h非常小(通常不超過3)。

綜上所述,用B-Tree作為索引結構效率是非常高的。

而紅黑樹這種結構,h明顯要深的多。由於邏輯上很近的節點(父子)物理上可能很遠,無法利用區域性性,所以紅黑樹的I/O漸進複雜度也為O(h),效率明顯比B-Tree差很多。

上文還說過,B+Tree更適合外存索引,原因和內節點出度d有關。從上面分析可以看到,d越大索引的效能越好,而出度的上限取決於節點內key和data的大小:

dmax = floor(pagesize / (keysize + datasize + pointsize)) (pagesize – dmax >= pointsize)

dmax = floor(pagesize / (keysize + datasize + pointsize)) - 1 (pagesize – dmax < pointsize)

floor表示向下取整。由於B+Tree內節點去掉了data域,因此可以擁有更大的出度,擁有更好的效能。

這一章從理論角度討論了與索引相關的資料結構與演算法問題,下一章將討論B+Tree是如何具體實現為MySQL中索引,同時將結合MyISAM和InnDB儲存引擎介紹非聚集索引和聚集索引兩種不同的索引實現形式。


相關推薦

MySQL效能調——索引索引優化

——索引優化,可以說是資料庫相關優化、理解尤其是查詢優化中最常用的優化手段之一。所以,只有深入索引的實現原理、儲存方式、不同索引間區別,才能設計或使用最優的索引,最大幅度的提升查詢效率! 一、BTree索引 1、概述 Mysql資料庫中使用最頻繁的索引型別,基本所有儲存引

java應用效能調System的gc垃圾回收方法

一、什麼是System.gc()? System.gc()是用Java,C#和許多其他流行的高階程式語言提供的API。當它被呼叫時,它將盡最大努力從記憶體中清除垃圾(即未被引用的物件)。名詞解釋:GC,Garbage Collection,垃圾回收,下文會經常使用。 二、誰可以呼叫System.gc()? &

MySQL效能調my.cnf

提供一個MySQL 5.6版本適合在1GB記憶體VPS上的my.cnf配置檔案: [client] port =3306 socket =/tmp/mysql.sock [mysqld] port =3306 socket =/tmp/mysql.sock basedi

MySQL效能優化總結___本文乃《MySQL效能調架構設計》讀書筆記!

一、MySQL的主要適用場景 1、Web網站系統 2、日誌記錄系統 3、資料倉庫系統 4、嵌入式系統 二、MySQL架構圖:   三、MySQL儲存引擎概述 1)MyISAM儲存引擎 MyISAM儲存引擎的表在資料庫中,每一個表

mysql效能調(四)——聚簇索引索引覆蓋

1、聚簇索引      這裡說的,聚簇索引是相對InnoDB資料庫引擎來說的,講的是聚簇索引隨機主鍵值的效率      對於InnoDB來說,主鍵儘量用整型,並且是遞增的比較好,因為新增的時候,如果是隨機主鍵插入,會存在節點分裂

mysql效能調筆記(二)--查詢優化索引

一、Mysql執行查詢流程                                                                           mysql執行查詢的流程 mysql執行查詢內部路程:1.客服端傳送一條查詢給伺服器

MySQL效能調架構設計-筆記

MySQL的主要適用場景 ①Web網站系統:免費開源、安裝配置簡單。 ②日誌記錄系統:MyISAM實現高效能插入和查詢。 ③資料倉庫系統:免費支援主從複製。 InnoDB儲存引擎的特點: a. 支援事務安全

JVM效能調的6大步驟,及關鍵調引數

JVM效能調優的6大步驟,及關鍵調優引數詳解 JVM效能調優方法和步驟 1.監控GC的狀態 2.生成堆的dump檔案 3.分析dump檔案 4.分析結果,判斷是否需要優化 5.調整GC型別和記憶體分配 6.不斷分析

MySQL效能調——鎖定機制優化分析

——針對多執行緒的併發訪問,任何一個數據庫都有其鎖定機制,它的優劣直接關係著資料的一致完整性與資料庫系統的高併發處理效能。鎖定機制也因此成了各種資料庫的核心技術之一。不同資料庫儲存引擎的鎖定機制是不同

MySQL效能調架構設計(六)—— MySQL資料庫鎖定機制

前言 在說鎖定機制之前,有必要理解下併發與並行的基本概念。 併發是指一臺處理器上同時處理多個任務,並行是指多個處理器同時處理多個任務,如hadoop分散式叢集。 通俗的講,併發就是不同執行緒同時幹一件事情,並行就是不同執行緒同時幹不同的事情。 所以併發程式設計的目

讀《MySQL效能調架構設計》筆記之充分利用 Explain和Profiling

1.1. Explain 的使用     我們先看一下在MySQL Explain 功能中給我們展示的各種資訊的解釋:     ◆ ID:MySQL Query Optimizer選定的執行計劃中查詢的序列號。表示查詢中執行select子句或操作表的順序,id值越大優先順序

MYSQL效能調: 對聚簇索引和非聚簇索引的認識

聚簇索引是對磁碟上實際資料重新組織以按指定的一個或多個列的值排序的演算法。特點是儲存資料的順序和索引順序一致。 一般情況下主鍵會預設建立聚簇索引,且一張表只允許存在一個聚簇索引。 在《資料庫原理》一書中是這麼解釋聚簇索引和非聚簇索引的區別的: 聚簇索引的葉子節點就

MySQL 效能調技巧

技巧#1:確定MySQL的最大連線數 對於MySQL的最大連線數,一次最好是傳送5個請求到Web伺服器。對Web伺服器的5個請求中的一部分將用於CSS樣式表,影象和指令碼等資源。由於諸如瀏覽器快取等原因,要獲得準確的MySQL到Web伺服器的請求比率可能很困難; 要想得到一個確切的數字,就需要分

MySQL效能調-使用ROLLUP代替UNION ALL

需求:統計各個活動的用券總金額和所有活動的用券總金額 原SQL語句如下(表明比較敏感,不便展示): select active_code,SUM(rp_amount) totalReward from xxx_xxx_xxx_xxx group by active_cod

mysql效能調(三)——列選取原則

1、列型別選擇       1)整型 > data、time > char、varchar > blob            整型、date、time運算快 &nb

mysql效能調(二)——查詢mysql程序狀態

除了可以檢視資料庫狀態,還可以觀察mysql程序狀態 用show processlist 或者開啟慢查詢,獲取有問題的sql(而用profiling以及explain分析sql語句我們暫時以後再說) mysql -uroot -e 'show processlist' 看資料庫狀

mysql效能調(一)——查詢資料庫狀態

所謂效能調優,首先要發現問題,才能知道怎麼進行效能調優噻,所以我們先從發現問題開始 1、show status  查詢資料庫狀態      其中監控伺服器狀態比較重要的幾個引數是: Queries 進行多少次查

MySQL效能調

1、修改伺服器BIOS設定 1.1.選擇performance Per watt Optimized(DAPC)模式、發揮CPU最大效能。 1.2.Memory Frequency(記憶體頻率) 選擇Maximum performance(最近效能)。 1.3.

YARN的Memory和CPU調配置

Hadoop YARN同時支援記憶體和CPU兩種資源的排程,本文介紹如何配置YARN對記憶體和CPU的使用。YARN作為一個資源排程器,應該考慮到叢集裡面每一臺機子的計算資源,然後根據application申請的資源進行分配Container。Container是YARN裡面

主從同步、讀寫分離、mysql效能調(軟優化)

 配置mysql主從同步1 主從同步的作用:讓slave身份的資料庫伺服器自動同步 master身份的資料庫伺服器上的資料。 一、主資料庫伺服器的配置192.168.4.121 使用者授權mysql> grant replication slave on *.* to [email