索引是儲存引擎用於快速查到記錄的一種資料結構。索引也是一張表,該錶儲存了主鍵與索引字段,並指向實體表的記錄。
索引基礎
索引的缺點
索引的型別
假如有表如下:
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-treehash索引
假如有表如下: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') = 8784
,mysql
會在索引中查詢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)
中對資料進行排序,如果記憶體裝載不下,它會將磁碟上的資料進行分塊,再對各個資料塊進行排序,然後將各個塊合併成有序的結果集(實際上就是外排序)。對於filesort
,mysql
有兩種排序演算法。
索引和鎖
索引對於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查詢效能優化
響應時間過長。如果把查詢看做是乙個任務,那麼它由一系列子任務組成,每個子任務都會消耗一定的時間。如果要優化查詢,實際上優化其子任務,要麼消除其中一些子任務,要麼減少子任務的執行次數,要麼讓子任務執行得更快。查詢的生命週期 客戶端 伺服器 伺服器上解析 生成執行計畫 執行 返回結果給客戶端。其中 執行...