MySql 優化詳解(二)高效能的索引

2021-08-14 02:20:33 字數 3991 閱讀 6464

索引是儲存引擎用於快速查到記錄的一種資料結構。索引也是一張表,該錶儲存了主鍵與索引字段,並指向實體表的記錄。

索引基礎

索引的缺點

索引的型別

假如有表如下:

create

table people (

last_name varchar(50) not

null,

first_name varchar(50) not

null,

dob date

notnull,

gender enum('m', 'f') not

null,

key(last_name, first_name, dob)

);

其索引包含表中每一行的last_name、first_name和dob列。其結構大致如下:

索引儲存的值按索引列中的順序排列。可以利用b-tree索引進行全關鍵字、關鍵字範圍和關鍵字字首查詢,當然,如果想使用索引,你必須保證按索引的最左邊字首(leftmost prefix of the index)來進行查詢。

由於b-樹中的節點都是順序儲存的,所以可以利用索引進行查詢(找某些值),也可以對查詢結果進行order by。當然,使用b-tree索引有以下一些限制:

更多資料:mysql索引演算法原理解析 b-tree

hash索引

mysql中,只有memory儲存引擎顯示支援hash索引,是memory表的預設索引型別。innodb可以建立hash索引但是實際上仍然是b-tree的索引,不過innodb有還有一種實現方法:自適應雜湊索引。innodb儲存引擎會監控對錶上索引的查詢。假設觀察到建立雜湊索引能夠帶來速度的提公升,則建立雜湊索引。參考:警惕 innodb 和 myisam 建立 hash 索引陷阱。

假如有表如下:

create

table testhash (

fname varchar(50) not

null,

lname varchar(50) not

null,

keyusing hash(fname)

) engine=memory;

包含資料如下:

索引使用hash函式f(),將返回如下值:

f('arjen') = 2323

f('baron') = 7437

f('peter') = 8784

f('vadim') = 2458

則雜湊索引的資料結構:

當你執行:

select lname from testhash where fname='peter';
mysql會計算』peter』的hash值,然後通過它來查詢索引的行指標。因為f('peter') = 8784mysql會在索引中查詢8784,得到指向記錄3的指標。因為索引自己僅僅儲存很短的值,所以,索引非常緊湊。hash值不取決於列的資料型別,乙個tinyint列的索引與乙個長字串列的索引一樣大。

空間(r-tree)索引

myisam支援空間索引,主要用於地理空間資料型別,例如geometry。

全文(full-text)索引

全文索引是myisam的乙個特殊索引型別,主要用於全文檢索。

索引的種類

索引的建立原則

選擇識別符號

選擇合適的識別符號是非常重要的。選擇時不僅應該考慮儲存型別,而且應該考慮mysql是怎樣進行運算和比較的。一旦選定資料型別,應該保證所有相關的表都使用相同的資料型別。

選擇索引和利用索引查詢的原則

索引覆蓋查詢是很快的。

如果乙個索引包含了查詢需要的所有列,那麼儲存引擎就你不需要再回表查行。這避免了大量的單行訪問。

高效能的索引策略

選擇合適的索引列順序

乙個經驗法則是:將選擇性最高的列放到索引最前列。但是場景不同,試用的準則也可能不同,所以對於合適索引列順序的選擇還需要具體分析。

聚簇索引

聚簇索引並不是一種單獨的索引型別,而是一種資料儲存方式。innodb的聚簇索引實際上在同乙個結構中保持了b-tree索引和資料行。當表有聚簇索引時,它的資料行實際上存放在索引的葉子頁(leaf page)中。聚簇表示資料行和相鄰的鍵值緊湊地儲存在一起。因為無法同時把資料行存放在兩個不同的地方,所以乙個表只能有乙個聚簇索引。

聚簇索引的結構:

innodb對主鍵建立聚簇索引。如果你不指定主鍵,innodb會用乙個具有唯一且非空值的索引來代替。如果不存在這樣的索引,innodb會定義乙個隱藏的主鍵,然後對其建立聚簇索引。一般來說,dbms` 都會以聚簇索引的形式來儲存實際的資料,它是其它二級索引的基礎。

覆蓋索引

覆蓋索引不能是任何索引,只有b-tree索引儲存相應的值。對於索引覆蓋查詢(index-covered query),使用explain時,可以在extra一列中看到using index

利用索引排序

mysql中,有兩種方式生成有序結果集:一是使用filesort,二是按索引順序掃瞄。利用索引進行排序操作是非常快的,而且可以利用同一索引同時進行查詢和排序操作。當索引的順序與order by中的列順序相同且所有的列是同一方向(全部公升序或者全部降序)時,可以使用索引來排序。如果查詢是連線多個表,僅當order by中的所有列都是第乙個表的列時才會使用索引。其它情況都會使用filesort

mysql不能使用索引進行排序時,就會利用自己的排序演算法(快速排序演算法)在記憶體(sort buffer)中對資料進行排序,如果記憶體裝載不下,它會將磁碟上的資料進行分塊,再對各個資料塊進行排序,然後將各個塊合併成有序的結果集(實際上就是外排序)。對於filesortmysql有兩種排序演算法。

索引和鎖

索引對於innodb非常重要,因為它可以讓查詢鎖更少的元組。這點十分重要,因為mysql 5.0中,innodb直到事務提交時才會解鎖。有兩個方面的原因:首先,即使innodb行級鎖的開銷非常高效,記憶體開銷也較小,但不管怎麼樣,還是存在開銷。其次,對不需要的元組的加鎖,會增加鎖的開銷,降低併發性。

innodb僅對需要訪問的元組加鎖,而索引能夠減少innodb訪問的元組數。但是,只有在儲存引擎層過濾掉那些不需要的資料才能達到這種目的。一旦索引不允許innodb那樣做(即達不到過濾的目的),mysql伺服器只能對innodb返回的資料進行where操作,此時,已經無法避免對那些元組加鎖了:innodb已經鎖住那些元組,伺服器無法解鎖了。

《高效能MySQL》讀書筆記之建立高效能的索引

索引是儲存引擎用於快速找到記錄的一種資料結構。索引優化是對查詢效能優化的最有效手段。索引能夠輕易將查詢效能提高幾個數量級。建立乙個最優的索引經常需要重寫查詢。5.1 索引基礎 在mysql中,儲存引擎首先在索引中找到對應值,然後根據匹配的索引記錄找到對應的資料行。索引可以包含乙個或多個列的值。如果索...

高效能Mysql筆記 優化

了解查詢的整個生命週期,清楚每個階段的時間消耗情況 參考select profiling 檢視profiling是否開啟 set profiling 1 開啟profiling show profiles 檢視每條查詢的效能 show profile for query id 檢視query id的...

《高效能MySQL》之MySQL查詢效能優化

響應時間過長。如果把查詢看做是乙個任務,那麼它由一系列子任務組成,每個子任務都會消耗一定的時間。如果要優化查詢,實際上優化其子任務,要麼消除其中一些子任務,要麼減少子任務的執行次數,要麼讓子任務執行得更快。查詢的生命週期 客戶端 伺服器 伺服器上解析 生成執行計畫 執行 返回結果給客戶端。其中 執行...