Mysql索引概念:
說說Mysql索引,看到一個很少比如:索引就好比一本書的目錄,它會讓你更快的找到內容,顯然目錄(索引)並不是越多越好,假如這本書1000頁,有500也是目錄,它當然效率低,目錄是要占紙張的,而索引是要占磁盤空間的。
Mysql索引主要有兩種結構:B+Tree索引和Hash索引.
Hash索引
MySQL中,只有Memory(Memory表只存在內存中,斷電會消失,適用於臨時表)存儲引擎顯示支持Hash索引,是Memory表的默認索引類型,盡管Memory表也可以使用B+Tree索引。hsah索引把數據的索引以hash形式組織起來,因此當查找某一條記錄的時候,速度非常快。當時因為是hash結構,每個鍵只對應一個值,而且是散列的方式分布。所以他並不支持范圍查找和排序等功能。
B+樹索引
B+tree是mysql使用最頻繁的一個索引數據結構,是Inodb和Myisam存儲引擎模式的索引類型。相對Hash索引,B+樹在查找單條記錄的速度比不上Hash索引,但是因為更適合排序等操作,所以他更受用戶的歡迎。畢竟不可能只對數據庫進行單條記錄的操作。
帶順序訪問指針的B+Tree
B+Tree所有索引數據都在葉子結點上,並且增加了順序訪問指針,每個葉子節點都有指向相鄰葉子節點的指針。
這樣做是為了提高區間查詢效率,例如查詢key為從18到49的所有數據記錄,當找到18后,只需順着節點和指針順序遍歷就可以一次性訪問到所有數據節點,極大提到了區間查詢效率。
大大減少磁盤I/O讀取
數據庫系統的設計者巧妙利用了磁盤預讀原理,將一個節點的大小設為等於一個頁,這樣每個節點只需要一次I/O就可以完全載入。
為了達到這個目的,在實際實現B- Tree還需要使用如下技巧:
每次新建節點時,直接申請一個頁的空間,這樣就保證一個節點物理上也存儲在一個頁里,加之計算機存儲分配都是按頁對齊的,就實現了一個node只需一次I/O。
B-Tree中一次檢索最多需要h-1次I/O(根節點常駐內存),漸進復雜度為O(h)=O(logdN)。一般實際應用中,出度d是非常大的數字,通常超過100,因此h非常小(通常不超過3)。而紅黑樹這種結構,h明顯要深的多。由於邏輯上很近的節點(父子)物理上可能很遠,無法利用局部性,所以紅黑樹的I/O漸進復雜度也為O(h),效率明顯比B-Tree差很多。
1、選擇索引的數據類型
MySQL支持很多數據類型,選擇合適的數據類型存儲數據對性能有很大的影響。通常來說,可以遵循以下一些指導原則:
(1)越小的數據類型通常更好:越小的數據類型通常在磁盤、內存和CPU緩存中都需要更少的空間,處理起來更快。
(2)簡單的數據類型更好:整型數據比起字符,處理開銷更小,因為字符串的比較更復雜。在MySQL中,應該用內置的日期和時間數據類型,而不是用字符串來存儲時間;以及用整型數據類型存儲IP地址。
(3)盡量避免NULL:應該指定列為NOT NULL,除非你想存儲NULL。在MySQL中,含有空值的列很難進行查詢優化,因為它們使得索引、索引的統計信息以及比較運算更加復雜。你應該用0、一個特殊的值或者一個空串代替空值。
2、選擇主鍵類型
選擇合適的標識符是非常重要的。選擇時不僅應該考慮存儲類型,而且應該考慮MySQL是怎樣進行運算和比較的。一旦選定數據類型,應該保證所有相關的表都使用相同的數據類型。
(1) 整型:通常是作為標識符的最好選擇,因為可以更快的處理,而且可以設置為AUTO_INCREMENT。
(2) 字符串:盡量避免使用字符串作為標識符,它們消耗更好的空間,處理起來也較慢。而且,通常來說,字符串都是隨機的,所以它們在索引中的位置也是隨機的,這會導致頁面分裂、隨機訪問磁盤,聚簇索引分裂(對於使用聚簇索引的存儲引擎)。
Mysql常見索引有:主鍵索引、唯一索引、普通索引、全文索引、組合索引
PRIMARY KEY(主鍵索引) ALTER TABLE `table_name` ADD PRIMARY KEY ( `col` )
UNIQUE(唯一索引) ALTER TABLE `table_name` ADD UNIQUE (`col`)
INDEX(普通索引) ALTER TABLE `table_name` ADD INDEX index_name (`col`)
FULLTEXT(全文索引) ALTER TABLE `table_name` ADD FULLTEXT ( `col` )
組合索引 ALTER TABLE `table_name` ADD INDEX index_name (`col1`, `col2`, `col3` )
Mysql各種索引區別:
普通索引:最基本的索引,沒有任何限制
唯一索引:與"普通索引"類似,不同的就是:索引列的值必須唯一,但允許有空值。
主鍵索引:它 是一種特殊的唯一索引,不允許有空值。
全文索引:僅可用於 MyISAM 表,針對較大的數據,生成全文索引很耗時好空間。
聯合索引:為了更多的提高mysql效率可建立組合索引,遵循”最左前綴“原則。創建復合索引時應該將最常用(頻率)作限制條件的列放在最左邊,依次遞減。
聯合索引的好處:覆蓋索引,這一點是最重要的,眾所周知非主鍵索引會先查到主鍵索引的值再從主鍵索引上拿到想要的值。但是覆蓋索引可以直接在非主鍵索引上拿到相應的值,減少一次查詢。
復合索引和普通索引都是用一棵B+樹表示的。
如果是單列,就按這列key數據進行排序。
如果是多列,就按多列數據排序,
例如有(1,1)(1,4)(2,2)(1,3) (2,1)(1,2)(2,3) (2,4)
那在索引中的葉子節點的數據順序就是(1,1)(1,2)(1,3) (1,4)(2,1)(2,2)(2,3) (2,4)
這也是為什么查詢復合索引的前綴是可以用到索引的原因
組合索引最左字段用in是可以用到索引的,最好explain一下select。