1. 程式人生 > >MySQL高階篇(一)——索引

MySQL高階篇(一)——索引

引言

            MySQL索引比作書本的章節目錄,這個類比合理嗎?

概述

            對於引言中的疑問?特給出如下定義:索引是幫助MySQL快速查詢和排序的一種資料結構。將索引比作章節目錄不是很合理,眾所周知,章節目錄基本都是有序的,而索引並不算是順序的資料結構,就比如MySQL常用都是B樹索引,類似資料結構的排序二叉樹。

內容

             一 分類

             1 按照型別:B樹(聚集索引、次要索引、覆蓋索引、符合索引、字首索引)、雜湊索引(hashindex)

             2 表現形式:

                (1)單值:一個索引值包含單個列,一個表可以有多個單列索引,一張表建立索引最多不超過5個;

                (2)唯一:索引列的值必須唯一,但允許有空值。主鍵建立後一定包含一個唯一索引,唯一索引並不一定就是主鍵。

                (3)複合:在表的多個列上建立的索引。

        二 結構:BTree索引、Hash索引、full-text全文索引、R-Tree索引

             三 優、劣勢

             1 優勢

                (1)提高資料檢索的效率,降低資料庫的IO成本

                (2)通過索引列對資料進行排序,降低資料排序的成本,降低了CPU的消耗

             2 劣勢

                (1)索引佔用一定的空間

                (2)提高了查詢,降低了更新表的速度

                (3)當MySQL有大量資料,索引優化耗費大量時間

        四 使用

             1 檢索原理(以B樹為例)

                

                 如上圖,是一顆b+樹,這裡只說一些重點,淺藍色的塊我們稱之為一個磁碟塊,可以看到每個磁碟塊包含幾個資料項(深藍色所示)和指標(黃色所示),如磁碟塊1包含資料項17和35,包含指標P1、P2、P3,P1表示小於17的磁碟塊,P2表示在17和35之間的磁碟塊,P3表示大於35的磁碟塊。真實的資料存在於葉子節點即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非葉子節點只不儲存真實的資料,只儲存指引搜尋方向的資料項,如17、35並不真實存在於資料表中。

             2 基本語法

                (1)檢視:SHOW INDEX FROM table_name\G

                (2)建立:CREATE [UNIQUE] INDEX  indexName ON mytable(columnname(length));

                (3)刪除:DROP INDEX [indexName] ON mytable;

                (4)使用(ALTER命令):

                         ALTER TABLE tbl_name ADD PRIMARY KEY (column_list);新增一個主鍵,索引值必須是唯一的,且不能為NULL。

                         ALTER TABLE tbl_name ADD UNIQUE index_name(column_list);建立索引的值必須是唯一的(除了NULL外,NULL可能會出現多次)。

                         ALTER TABLE tbl_name ADD INDEX index_name(column_list);新增普通索引,索引值可出現多次。

                         ALTER TABLE tbl_name ADD FULL TEXT index_name(column_list);索引為FULLTEXT,用於全文索引。

             3 場景

                (1)需要建立索引

                       1)主鍵自動建立唯一索引

                       2)頻繁作為查詢條件的欄位

                       3)查詢中與其它表關聯的欄位,外來鍵關係建立索引

                       4)高併發下傾向建立組合索引

                       5)查詢中排序的欄位

                       6)查詢中統計或分組欄位

                (2)不要建立索引

                       1)頻繁更新的欄位

                       2)where條件裡用不到的欄位

                       3)表記錄太少

                       4)經常增刪改的表

                       5)資料重複且分佈平均的表字段

             4 優化

                (1)問題(索引失效)

                      1)違反最佳左字首法則

                      2)在索引列上做如下任何操作(計算、函式、(自動or手動)型別轉化)

                      3)使用不等於的時候無法使用索引

                      4)is null,is not null也無法使用索引

                      5)like以萬用字元開頭('%abc....'),索引失效,變為全表掃描操作

                      6)字串不加單引號

                      7)用or來連線

                      8)儲存引擎不能使用索引中範圍條件右邊的列

                 (2)優化建議

                      1)單值索引:儘量選擇針對當前query過濾性更好的索引

                      2)組合索引:當前Query中過濾性最好的欄位在索引欄位順序中,位置越靠前越好;儘量選擇可以能夠包含當前query中的where子句中更多欄位的索引

                      3)儘可能通過分析統計資訊和調整query的寫法來達到選擇合適索引的目的

                 (3)面試題:like '%字串%'時索引失效問題?覆蓋索引

總結

             一般MySQL資料庫的資料量達到了百萬級別,才有可能用到索引,百萬級以下的資料量,MySQL本身的優化機制就可以滿足我們增刪改的操作。所以索引不一定必須使用,這只是一種資料庫量大之後,推出的一種效能優化方式。