1. 程式人生 > 其它 >【Java學習筆記(一百零五)】之MYSQL 索引優化,儲存優化

【Java學習筆記(一百零五)】之MYSQL 索引優化,儲存優化

技術標籤:Java學習筆記MYSQL資料庫搜尋引擎索引mysql

本文章由公號【開發小鴿】釋出!歡迎關注!!!


老規矩–妹妹鎮樓:

一. 索引優化

(一) 索引的介紹

索引從字面上就可以看出類似一個指向資料庫中資料的指標,沒有索引的時候只能通過搜尋資料庫中的資料來查詢;通過索引,只需要查詢索引中有無關聯的資料就可以返回查詢結果,大大提高了查詢的效能。

(二) 新增索引

在建立資料表的時候,可以通過KEY關鍵字新增索引:

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;

新增number項的索引後,當我們通過number的值來搜尋資料庫時,就會使用到索引。

(三) 索引的型別

1. 主鍵索引PRIMARY KEY

特殊的唯一索引,不允許有空值,一般是在建表的時候同時建立主鍵索引。

PRIMARY KEY (“id”)

2. 唯一索引UNIQUE

唯一索引列的值必須唯一,但允許有空值,可以在建表的時候指定,也可以修改表結構。

UNIQUE KEY “num” (“number”) USING BTREE

3. 普通索引INDEX

基本的索引,沒有限制,可在建表時指定,也可以修改表結構、

KEY “num” (“number”) USING BTREE

4. 組合索引INDEX

索引分單列索引和組合索引。單列索引即一個索引僅包含單個列,一個表可以有多個單列索引;組合索引,即一個索引中包含多個列,組合索引遵循著左字首匹配的原則,只有使用到左邊的列,索引才會被使用,如果單獨使用右邊的列而不使用左邊的列,那麼索引是無法使用的。如下所示,只有查詢了number列,name列才能夠使用。

KEY “num” (“number”, “name”) USING BTREE

5. 全文索引FULLTEXT

全文索引(全文檢索)是目前搜尋引擎使用的一種技術,能夠利用分詞技術分析出文本中關鍵字的頻率和重要性,篩選出想要的搜尋結果。

(四) 索引的儲存結構

1. BTree索引

MYSQL普遍使用B+ Tree作為索引方案,即BTree。BTree索引以B+樹作為儲存結構,能夠加快資料的查詢速度,並且適合進行範圍查詢。通常用於全值匹配的查詢,即一個值要完整地匹配上;同樣在聯合索引時遵循最左字首匹配原則,還能夠匹配列的字首進行模糊查詢,最重要的是可以進行範圍查詢,對一個範圍的值進行查詢,而不只是搜尋一個相等的值。同時,它還是一個只訪問索引的查詢。


2. 雜湊索引

雜湊索引在MYSQL中使用的並不多,目前主要是Memory儲存引擎使用,是預設的索引型別。所謂的雜湊索引,就是通過一定的hash演算法,將需要索引的鍵值進行Hash運算,然後將得到的Hash值存入一個Hash表中,每次需要檢索時,對於檢索條件進行同樣的Hash運算,並與Hash表比較得出結果。

Hash索引只能進行單值相等查詢,不能進行範圍查詢;

無法對資料進行排序,因為Hash索引中儲存的是Hash運算的結果值,與原有的值排序無關;

不能利用部分索引鍵查詢,對於聯合索引,Hash索引是將聯合索引中的所有列作為鍵值計算Hash值的,因此無法使用其中的部分索引鍵查詢;

Hash索引無法避免表掃描,因為Hash運算可能會對不同的鍵值產生相同的Hash值,需要通過全表掃描的方式來搜素出所有Hash值相等的鍵值,進行排除;

Hash索引遇到大量Hash值相等的情況效能不一定就比BTree好。


3. Full-text全文索引

全文索引,在MYSQL中僅有MyISAM和InnoDB儲存引擎支援。對於文字物件,如果使用普通的索引,只能匹配前幾個字元或者通過LIKE %word%來匹配中間的字元,這樣非常麻煩且低效。全文索引會為文字生成一份單詞的清單,在索引時根據這個單詞的清單來索引。

對於較大的資料集,將資料新增到一個沒有全文索引的表,然後再新增全文索引的速度比將資料直接新增到一個已有全文索引的表更快;

生成全文索引會消耗大量時間和空間;

5.6版本前全文索引只能使用MyISAM儲存引擎,之後添加了InnoDB儲存引擎;

5.7版本後使用ngram外掛開始支援中文;

檢索的字串長度至少4個位元組,如果太短無法得到預期的結果。

(五) 索引的使用

1. 索引的缺點

索引會增加寫操作的成本,如空間成本;

索引過多,則生成的查詢計劃也更多,查詢優化器的查詢時間也會更多;

只有當建立索引的優勢大於消耗時,才是最優的選擇。

2. 使用索引的場景

主鍵自動建立唯一索引;

常作為查詢條件的列要建立索引,如WHERE和ORDER BY語句中的列;

作為排序的列要建立索引;

查詢中與其他表關聯的欄位,外來鍵關係需要建立索引;

高併發條件下需要建立組合索引;

3. 不使用索引的場景

列中有大量重複的值不單獨建立索引,因為沒有意義;

表中記錄過少不要建立索引,浪費資源;

不會用於查詢的類不要建立索引;

二. 儲存優化

通過show engines 命令可以查詢出MYSQL支援的儲存引擎。這裡主要討論Innobdn, MyISAM 儲存引擎。

(一) InnoDB儲存引擎

1. 特點

(1) InnoDB儲存引擎提供了具有提交,回滾和崩潰恢復能力的事務安全,也正是因為事務,寫操作的處理效率更差且會佔用更多空間儲存資料和索引;

(2) 提供了對資料庫事務ACID(原子性,一致性,隔離性,永續性)的支援,實現了SQL標準的四種隔離級別;

(3) 記憶體中建立緩衝池,用於緩衝資料和索引;

(4) 使用InnoDB引擎的表不會儲存表的具體行數,所以需要掃描整個表才能夠計算行數;

(5) 使用行鎖,粒度更小,寫操作不會鎖定整個表,高併發時,效率更高;

(6) 清空資料量大的表時,非常緩慢,因為InnoDB必須處理表的每一行,根據InnoDB的事務設計規則,首先需要將“刪除動作”寫入“事務日誌”,然後寫入實際的表,所以清空大表時,直接drop table然後重建。。

2. 使用場景

頻繁的update/insert操作,處理高併發的寫請求;

只有InnoDB支援事務,可通過日誌+事務回滾恢復;

支援外來鍵約束,列屬性AUTO_INCREMENT支援;

(二) MyISAM儲存引擎

1. 特點

(1) 不支援事務,不支援外來鍵;

(2) 每個MyISAM在儲存時分成三個檔案,副檔名分別為

frm :儲存表定義,結構
MYD(MYData): 儲存資料
MYI(MYIndex): 儲存索引

(3) 不同MyISAM表的索引檔案和資料檔案可以放到不同的路徑中;

(4) MyISAM型別的表提供修復的工具;

(5) 5.6以前,只有MyISAM支援全文索引;

2. 使用場景

插入不頻繁,查詢頻繁的場景,小型應用考慮使用MyISAM,效率更高。


(三) MyISAM和InnoDB的區別

  1. MyISAM是非事務安全的,InnoDB是事務安全的;

  2. MyISAM的鎖粒度是表級別的,InnoDB是行級別的;

  3. MyISAM不支援外來鍵,InnoDB支援;

  4. MyISAM簡單,效率上優於InnoDB,小型應用選擇MyISAM;

  5. InnoDB表比MyISAM表更加安全;

(四) 儲存優化

在儲存資料時,可以通過以下的設定來優化效能。

1. 禁用索引

對於使用索引的表,插入記錄時,Mysql會對插入的資料建立索引,如果插入大量的資料,同步建立索引會降低插入速度,我們可以在批量插入資料之前禁用索引,在資料插入完成後再開啟索引,這樣建立索引的操作就只需要一次即可。

禁用索引的語句:

ALTER TABLE table_name DISABLE KEYS

開啟索引的語句:

ALTER TABLE table_name ENABLE KEYS

InnoDB引擎需要這樣操作,而MyISAM引擎是直接對空表批量插入資料後再建立索引,因此不需要這樣做。

2. 禁用唯一性檢查

唯一性校驗會降低插入資料的速度,同樣的可禁用在完成插入後開啟:

禁用唯一性檢查的語句:

SET UNIQUE_CHECKS = 0

開啟唯一性檢查的語句:

SET UNIQUE_CHECKS = 1

3. 禁用外來鍵檢查

禁用:

SET foreign_key_checks = 0

開啟:

SET foreign_key_checks = 1

4. 禁止自動提交

禁止事務的自動提交操作,在資料完成之後統一進行事務的提交。

禁用:

SET autocommit =0

開啟:

SET autocommit =1