數據庫優化專題---9、索引優化

數據庫優化專題—1、表的主鍵用數字還是UUID
數據庫優化專題—2、邏輯刪除還是物理刪除
數據庫優化專題—3、千萬記錄如何快速分頁
數據庫優化專題—4、讀多寫少和讀多寫多
數據庫優化專題—5、刪改數據如何避免鎖表
數據庫優化專題—6、如何避免偷換交易中的商品信息
數據庫優化專題—7、SQL語句優化
數據庫優化專題—8、Mysql參數優化
數據庫優化專題—9、索引優化

這節主要講解下索引以及如何優化。

索引的介紹

創建以下表:

CREATE TABLE `tb_table` ( 
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',  
 `name` varchar(20) DEFAULT NULL COMMENT '姓名', 
 `number` int(11) DEFAULT NULL COMMENT '編號',  
 PRIMARY KEY (`id`),  KEY `number` (`number`) 
 ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

執行以下sql,批量添加10條數據:

drop procedure if exists tb_insert; 
CREATE PROCEDURE tb_insert() 
BEGIN 
DECLARE i INT; 
SET i = 0; 
START TRANSACTION; 
WHILE i < 10 DO -- 10即插入10條數據    
INSERT INTO tb_table (`name`,`number`) VALUES (concat("張 三",i),i);   
SET i = i+1; 
END WHILE; 
COMMIT; 
END;
call tb_insert();

在表沒有添加索引和添加索引的時候,都執行以下查詢:
       然後再添加數據庫的數據,插入100萬條,再次測試有索引和沒有索引的查詢語句。
       通過上面的對比測試可以看出,索引是快速搜索的關鍵。MySQL索引的建立對於 MySQL的高效運行是很重要的。對於少量的數據,沒有合適的索引影響不是很大, 但是,當隨着數據量的增加,性能會急劇下降。
       索引的目的在於提高查詢效率,大家可以回憶之前學習的全文檢索技術。類似使 用字典,如果沒有目錄(索引),那麼我們要從字典的第一個字開始查詢到後一 個字纔能有結果,可能要把字典中所有的字看一遍才能找到要結果,而目錄(索 引)則能夠讓我們快速的定位到這個字的位置,從而找到我們要的結果。

索引的類型

  • 主鍵索引 PRIMARY KEY
    它是一種特殊的唯一索引,不允許有空值。一般是在建表的時候同時創建主鍵索引。
PRIMARY KEY (`id`)
  • 唯一索引 UNIQUE
    唯一索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。可以在創建表的時候指定,也可以修改表結構。
UNIQUE KEY `num` (`number`) USING BTREE
  • 普通索引 INDEX
    這是基本的索引,它沒有任何限制。可以在創建表的時候指定,也可以修改 表結構
KEY `num` (`number`) USING BTREE
  • 組合索引 INDEX
    一個表可以有多個單列索引,但這不是組合索引。組合索引,即一個索引包含多個列。
KEY `num` (`number`,`name`) USING BTREE

注意,組合索引前面索引必須要先使用,後面的索引才能使用。

  • 全文索引 FULLTEXT
    全文索引(也稱全文檢索)是目前搜索引擎使用的一種關鍵技術。它能夠利用 分詞技術等多種算法智能分析出文本文字中關鍵字詞的頻率及重要性,然後按 照一定的算法規則智能地篩選出我們想要的搜索結果。

索引的存儲結構

BTree索引

在前面的例子中我們看見有USING BTREE,這個是什麼呢?這個就是MySQL所使 用的索引方案,MySQL中普遍使用B+Tree做索引,也就是BTREE。

特點:

  • BTREE索引以B+樹的結構存儲數據
  • BTREE索引能夠加快數據的查詢速度
  • BTREE索引更適合進行行範圍查找

使用的場景:

  1. 全值匹配的查詢,例如根據訂單號查詢 order_sn=‘98764322119900’
  2. 聯合索引時會遵循左前綴匹配的原則,即左優先
  3. 匹配列前綴查詢,例如:order_sn like ‘9876%’
  4. 匹配範圍值的查找,例如:order_sn > ‘98764322119900’ 5. 只訪問索引的查詢

哈希索引

Memory存儲引擎中將Hash索引作爲默認的索引類型。所謂Hash索引,實際上就是 通過一定的Hash算法,將需要索引的鍵值進行Hash運算,然後將得到的Hash值存 入一個Hash表中。然後每次需要檢索的時候,都會將檢索條件進行相同算法的Hash 運算,然後再和Hash表中的Hash值進行比較並得出相應的信息。

特點:

  • Hash索引僅僅只能滿足“=”,“IN”和“<=>”查詢,不能使用範圍查詢;
  • Hash索引無法被利用來避免數據的排序操作;
  • Hash索引不能利用部分索引鍵查詢;
  • Hash索引在任何時候都不能避免表掃描;
  • Hash索引遇到大量Hash值相等的情況後性能並不一定就會比B-Tree索引高;

Full-text全文索引

Full-text索引也就是我們常說的全文索引,MySQL中僅有MyISAM和InnoDB存儲 引擎支持。
對於文本的大對象,或者較大的CHAR類型的數據,如果使用普通索引,那麼匹配 文本前幾個字符還是可行的,但是想要匹配文本中間的幾個單詞,那麼就要使用 LIKE %word%來匹配,這樣需要很長的時間來處理,響應時間會大大增加,這種情 況,就可使用時FULLTEXT索引了,在生成Full-text索引時,會爲文本生成一份單詞 的清單,在索引時根據這個單詞的清單來索引。

注意:

  • 對於較大的數據集,把數據添加到一個沒有Full-text索引的表,然後添加Fulltext索引的速度比把數據添加到一個已經有Full-text索引的錶快。
  • 針對較大的數據,生成全文索引非常的消耗時間和空間。
  • 5.6版本前的MySQL自帶的全文索引只能用於MyISAM存儲引擎,如果是其它數 據引擎,那麼全文索引不會生效。5.6版本和之後InnoDB存儲引擎開始支持全文 索引。
  • 在MySQL中,全文索引支隊英文有用,目前對中文還不支持。5.7版本之後通過 使用ngram插件開始支持中文。
  • 在MySQL中,如果檢索的字符串太短則無法檢索得到預期的結果,檢索的字符 串長度至少爲4字節。

雖然索引能夠爲查找帶來速度上的提升,但是也會對性能有一些損失。

  • 索引會增加寫操作的成本
  • 太多的索引會增加查詢優化器的選擇時間
    當創建索引帶來的好處多過於消耗的時候,纔是優的選擇

使用索引的場景

  • 主鍵自動建立唯一索引;
  • 經常作爲查詢條件在WHERE或者ORDER BY 語句中出現的列要建立索引; 作爲排序的列要建立索引;
  • 查詢中與其他表關聯的字段,外鍵關係建立索引 高併發條件下傾向建立組合索引;
  • 用於聚合函數的列可以建立索引,例如使用count(number)時,number列就要建立索引;

不使用索引的場景

  • 有大量重複的列不單獨建立索引;
  • 表記錄太少不要建立索引,因爲沒有太大作用;
  • 不會作爲查詢的列不要建立索引;

總結:
根據業務場景選擇是否添加索引,並選擇合理的索引,提升查詢效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章