1. 程式人生 > 資料庫 >MYSQL索引、儲存引擎

MYSQL索引、儲存引擎

記錄:

1,索引的資料結構:B+ Tree

2,查詢、刪除、插入如何操作:

查詢:首先在根節點進行二分查詢,找到一個key所在的指標,然後遞迴地在指標所指向的節點進行查詢。直到查詢到葉子節點,然後在葉子節點上進行二分查詢,找出key所對應的data。

插入刪除會破壞平衡樹的平衡性,因此插入刪除操作,需要對樹進行分裂、合併、旋轉等操作。

3,Mysql有哪些索引:

a. B+Tree 索引:大多數MYSQL儲存引擎的預設索引型別。

適用於:全鍵值、鍵值範圍和鍵字首查詢。鍵字首查詢只適用於最左字首查詢。
Innodb的B+Tree索引分為主索引和輔助索引。主索引的葉子節點data域記錄完整的資料記錄,這種索引方式稱為聚簇索引,因為無法把資料行存放在兩個不同的地方,所以一個表只能有一個聚簇索引。

輔助索引記錄葉子節點記錄主鍵的值,通過主鍵的值,去主索引表中查詢所需資料。

b. 雜湊索引:能夠以O(1)的時間進行查詢,失去了有序性

缺點:無法進行排序和分組;只支援精確查詢,無法用於範圍查詢和部分查詢。
注意:InnoDB 儲存索引有一個特殊的功能:自適應雜湊索引,當某個索引值被使用的非常頻繁時,會在B+Tree索引上再建立一個hash索引,這樣B+Tree索引具有雜湊索引的一些優點,方便快速雜湊查詢。

c. 全文索引:用於查詢文字中的關鍵詞,而不是直接比較是否相等。 原理:倒排索引實現,記錄關鍵詞到所在文件的對映。

查詢條件:MATCH AGAINST,不是普通的Where
Innodb引擎在5.6.4版本後開始支援全文索引

空間資料索引:MyiSAM引擎支援空間資料索引(R-Tree),用於儲存地理資料

4, 索引的優點有哪些:

  • 加快查詢速度,減少伺服器需要掃描的資料行數

  • 幫助伺服器避免進行排序和分組,以及避免建立臨時表(B+Tree索引是有序的,可以用於Order By和Group By操作),臨時表主要是在排序和分組的過程中建立,由於不需要排序和分子,也就不需要建立臨時表

  • 將隨機I/O變為順序I/O

5,什麼時候去使用索引:

  • 對於非常小的表,大部分情況下簡單的全表掃描比簡歷索引更高效
  • 對於中到大型的表,索引就非常有效
  • 對於特大型的表,建立和維護索引的代價會隨之增長。此情況下,需要用到一種技術可以直接區分出需要查詢的一組資料,而不是用一條記錄去匹配,例如分割槽技術

6,如何進行查詢優化?(3):分析+資料訪問+查詢方式

使用Explain進行分析

EXPLAIN用來分析SELECT查詢語句,通過分析結果來優化查詢語句。常見欄位:select_type:查詢型別,有簡單查詢、聯合查詢、子查詢等。key:使用的索引;rows:掃描的行數

優化資料訪問
  • 減少請求的資料量:只返回必要的列(儘量不用select *),只返回必要的行(limit限制資料數目);快取重複查詢的資料;
  • 減少服務端掃描的行數(使用索引)
重構查詢方式
  • 切分大查詢:一個大查詢如果一次性執行的話,可能會鎖住很多資料,佔滿整個事務日誌、耗盡資源、阻塞很多小的但重要的查詢。所以,可以通過for/while迴圈一次性查詢一定的量
  • 分解大連線查詢:將連線查詢分解成對每個單表的查詢,在伺服器後端進行關聯。
    優點:
    a. 快取更加高效,對於連線查詢,如果其中一個表發生變化,則整個查詢快取無法使用,分解後的多個查詢,即使其中 一個表發生改變,對於其他表的查詢快取依舊可以使用。
    b. 分解成單表後,這些單表查詢的快取,有可能被其他查詢語句適用到。
    c. 減少鎖競爭
    d. 在應用層進行連線,更容易對資料進行拆分,做到高效能和可伸縮

7,Mysql儲存引擎有哪些?隔離級別分別是什麼?

  • Innodb(預設):支援事務,行級鎖,外來鍵約束,表加密
    實現四個標準的隔離級別:預設級別可重複讀(REPEATABLE READ),在可重複讀隔離級別下,通過多版本控制(MVCC)+間隙鎖(Next-key locking)防止幻影讀
    主索引是聚簇索引,索引中儲存了資料,從而避免直接讀取磁碟。
    支援真正的線上熱備份。
  • MyISAM:不支援事務,不支援行級鎖,只有表級鎖,支援壓縮表,空間資料索引等。
    由於是表級鎖,當讀取時對需要讀到的所有表加共享鎖,寫入時對所有表加排它鎖,但在表有讀取操作的同時,也可以向表中插入新的記錄,被稱為併發插入(CONCURRENT INSERT)
    如果指定了DELAY_KEY_WRITE選項,每次修改執行完成後不會立即將修改的索引資料寫入磁碟,而是寫到記憶體中的鍵緩衝區,只有在清理鍵緩衝區或者關閉表的時候才會將對應的索引塊寫入磁碟。可以極大的提升寫入效能,但是在資料庫或者主機崩潰時會造成索引損壞,需要執行修復操作
  • Memory
  • Merge
  • ARCHIVE

8,如何進行索引優化?

  • 獨立的列:索引列不能是表示式的一部分,也不能是函式的引數,否則無法使用。
SELECT actor_id FROM db.actor where actor_id + 1 = 5
//無法使用索引
  • 多列索引(聯合索引):當需要使用多個列作為條件進行查詢時,使用多列索引比使用多個單列索引效能更好。
SELECT film_id, actor_id FROM film_actor WHERE actor_id = 1 AND film_id = 1
//建議使用多列索引
  • 索引列的順序:讓選擇性最強的索引列放在前面

索引的選擇性是指:不重複的索引值和記錄總數的比值。最大值為 1,此時每個記錄都有唯一的索引與其對應。選擇性越高,查詢效率也越高。

SELECT COUNT(DISTINCT staff_id)/COUNT(*) AS staff_id_select,
COUNT(DISTINCT customer_id)/COUNT(*) AS customer_id_select,
COUNT(*)
FROM payment

//結果:
  staff_id_selectivity: 0.0001
customer_id_selectivity: 0.0373
               COUNT(*): 16049

所用選擇customer_id列放在多列索引的前面

  • 字首索引:對於 BLOB、TEXT 和 VARCHAR 型別的列,必須使用字首索引,只索引開始的部分字元。對於字首長度的選取需要根據索引選擇性來確定。
  • 索引包含所有需要查詢的欄位的值。

具有以下優點:

索引通常遠小於資料行的大小,只讀取索引能大大減少資料訪問量。
一些儲存引擎(例如 MyISAM)在記憶體中只快取索引,而資料依賴於作業系統來快取。因此,只訪問索引可以不使用系統呼叫(通常比較費時)。
對於 InnoDB 引擎,若輔助索引能夠覆蓋查詢,則無需訪問主索引。