日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql单列索引和多列索引_浅谈MySQL索引优化

發布時間:2025/3/21 数据库 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql单列索引和多列索引_浅谈MySQL索引优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

索引基礎知識總結及常見索引優化手段


一、索引簡介

什么是索引?
  • MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取數據的數據結構。

  • 可以簡單理解為“排好序的快速查找數據結構”。

  • 一般來說索引本身也很大,不可能全部存儲在內存中,因此索引往往以索引文件的形式存儲的磁盤上

索引的優點
  • 類似大學圖書館建書目索引,提高數據檢索的效率,降低數據庫的IO成本

  • 通過索引列對數據進行排序,降低數據排序的成本,降低了CPU的消耗

索引的缺點
  • 雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件每次更新添加了索引列的字段,都會調整因為更新所帶來的鍵值變化后的索引信息

  • 實際上索引也是一張表,該表保存了主鍵與索引字段,并指向實體表的記錄,所以索引列也是要占用空間的

索引結構

MySQL支持諸多存儲引擎,而各種存儲引擎對索引的支持也各不相同,因此MySQL數據庫支持多種索引類型,如BTree索引,哈希索引,全文索引等等。

下面簡單介紹下BTree索引、B+Tree索引、聚簇索引與非聚簇索引

  • BTree索引

  • B+Tree索引

InnoDB使用B+Tree作為索引結構

拓展:B+Tree與B-Tree 的區別

1)B樹的關鍵字和記錄是放在一起的,葉子節點可以看作外部節點,不包含任何信息;B+樹的非葉子節點中只有關鍵字和指向下一個節點的索引,記錄只放在葉子節點中。
2)在B樹中,越靠近根節點的記錄查找時間越快,只要找到關鍵字即可確定記錄的存在;而B+樹中每個記錄的查找時間基本是一樣的,都需要從根節點走到葉子節點,而且在葉子節點中還要再比較關鍵字。從這個角度看B樹的性能好像要比B+樹好,而在實際應用中卻是B+樹的性能要好些。因為B+樹的非葉子節點不存放實際的數據,這樣每個節點可容納的元素個數比B樹多,樹高比B樹小,這樣帶來的好處是減少磁盤訪問次數。盡管B+樹找到一個記錄所需的比較次數要比B樹多,但是一次磁盤訪問的時間相當于成百上千次內存比較的時間,因此實際中B+樹的性能可能還會好些,而且B+樹的葉子節點使用指針連接在一起,方便順序遍歷(例如查看一個目錄下的所有文件,一個表中的所有記錄等),這也是很多數據庫和文件系統使用B+樹的緣故。

思考:為什么說B+樹比B樹更適合實際應用中操作系統的文件索引和數據庫索引?

1) B+樹的磁盤讀寫代價更低
B+樹的內部結點并沒有指向關鍵字具體信息的指針。因此其內部結點相對B 樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那么盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。
2) B+樹的查詢效率更加穩定
由于非終結點并不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

  • 聚簇索引與非聚簇索引

聚簇索引并不是一種單獨的索引類型,而是一種數據存儲方式。
術語‘聚簇’表示數據行和相鄰的鍵值聚簇的存儲在一起。
如下圖,左側的索引就是聚簇索引,因為數據行在磁盤的排列和索引排序保持一致。

聚簇索引的好處:

按照聚簇索引排列順序,查詢顯示一定范圍數據的時候,由于數據都是緊密相連,數據庫不不用從多個數據塊中提取數據,所以節省了大量的io操作。

聚簇索引的限制:

對于mysql數據庫目前只有innodb數據引擎支持聚簇索引,而Myisam并不支持聚簇索引。
由于數據物理存儲排序方式只能有一種,所以每個Mysql的表只能有一個聚簇索引。一般情況下就是該表的主鍵。
為了充分利用聚簇索引的聚簇的特性,所以innodb表的主鍵列盡量選用有序的順序id,而不建議用無序的id,比如uuid這種。

MySQL索引分類
  • 單值索引

即一個索引只包含單個列,一個表可以有多個單列索引
單獨建單值索引:
CREATE INDEX idx_customer_name ON customer(customer_name);
刪除索引:
DROP INDEX idx_customer_name on customer;

  • 唯一索引

索引列的值必須唯一,但允許有空值
單獨建唯一索引:
CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);
刪除索引:
DROP INDEX idx_customer_no on customer;

  • 主鍵索引

設定為主鍵后數據庫會自動建立索引,innodb為聚簇索引
單獨建主鍵索引:
ALTER TABLE customer add PRIMARY KEY customer(customer_no);
刪除建主鍵索引:
ALTER TABLE customer drop PRIMARY KEY;

  • 復合索引

即一個索引包含多個列
單獨建索引:
CREATE INDEX idx_no_name ON customer(customer_no,customer_name);
刪除索引:
DROP INDEX idx_no_name on customer;

  • 基本語法總結

創建:
CREATE [UNIQUE ] INDEX [indexName] ON table_name(column));
刪除:
DROP INDEX [indexName] ON mytable;
查看:
SHOW INDEX FROM table_name;
還可以使用ALTER命令

哪些情況需要創建索引?☆
  • 主鍵自動建立唯一索引

  • 頻繁作為查詢條件的字段應該創建索引

  • 查詢中與其它表關聯的字段,外鍵關系建立索引

  • 單鍵/組合索引的選擇問題, 組合索引性價比更高

  • 查詢中排序的字段,排序字段若通過索引去訪問將大大提高排序速度

  • 查詢中統計或者分組字段

哪些情況不要創建索引?☆
  • 表記錄太少

  • 經常增刪改的表或者字段

雖然提高了查詢速度,但是會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。更新表時,MySQL不僅要保存數據,還要保存一下索引文件。

  • Where條件里用不到的字段不創建索引

  • 過濾性不好的不適合建索引

二、借助Explain進行性能分析

Explain是什么(查看執行計劃)
  • 使用EXPLAIN關鍵字可以模擬優化器執行SQL查詢語句,從而知道MySQL是如何處理你的SQL語句的。分析你的查詢語句或是表結構的性能瓶頸。

Explain用途
  • 查看表的讀取順序

  • 查看哪些索引可以使用

  • 查看數據讀取操作的操作類型

  • 查看哪些索引被實際使用

  • 查看表之間的引用

  • 查看每張表有多少行被物理查詢

Explain使用方法
  • Explain + SQL語句

  • 執行計劃包含的信息:

各字段解釋:☆
  • id

select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序
id相同,執行順序由上至下


id不同,如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行
id相同不同,同時存在每個id號碼,表示一趟獨立的查詢。一個sql的查詢趟數越少越好。
  • select_type

查詢的類型,主要是用于區別普通查詢、聯合查詢、子查詢等的復雜查詢

  • table

    顯示這一行的數據是關于哪張表的

  • partitions

    代表分區表中的命中情況,非分區表,該項為null

  • type

type顯示的是訪問類型,是較為重要的一個指標,結果值從最好到最壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL一般來說,得保證查詢至少達到range級別,最好能達到ref。

  • possible_keys

    顯示可能應用在這張表中的索引,一個或多個。
    查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實際使用。

  • key

    實際使用的索引。如果為NULL,則沒有使用索引。查詢中若使用了覆蓋索引,則該索引和查詢的select字段重疊。

  • key_len

表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度。key_len字段能夠幫你檢查是否充分的利用了索引。

  • ref

    顯示索引的哪一列被使用了,如果可能的話,是一個常數。哪些列或常量被用于查找索引列上的值

  • rows

    rows列顯示MySQL認為它執行查詢時必須檢查的行數。rows越小,性能越高。

  • filtered

    這個字段表示存儲引擎返回的數據在server層過濾后,剩下多少滿足查詢的記錄數量的比例,注意是百分比,不是具體記錄數

  • Extra

包含不適合在其他列中顯示但十分重要的額外信息

三、查詢優化策略☆

單表優化策略
  • 全列匹配

  • 最左前綴法則

    如果索引了多列,要遵守最左前綴法則。指的是查詢從索引的最左前列開始命中并且不跳過索引中的列。

    注意:由于MySQL的查詢優化器會自動調整where子句的條件順序以使用適合的索引。

  • 不要在索引列上做任何操作(計算、函數、(自動or手動)類型轉換),會導致索引失效而轉向全表掃描

  • 存儲引擎不能使用索引中范圍條件右邊的列

  • mysql 在使用不等于(!= 或者<>)的時候無法使用索引,會導致全表掃描

  • is not null 無法使用索引,但is null是可以使用索引的

  • 若like以通配符開頭('%abc…'),則mysql索引失效,會變成全表掃描的操作

  • 字符串不加單引號索引失效

  • 練習

  • 對于單鍵索引,盡量選擇針對當前query過濾性更好的索引

  • 在選擇組合索引的時候,當前Query中過濾性最好的字段在索引字段順序中,位置越靠前越好。

  • 在選擇組合索引的時候,盡量選擇可以能夠包含當前query中的where字句中更多字段的索引

  • 在選擇組合索引的時候,如果某個字段可能出現范圍查詢時,盡量把這個字段放在索引次序的最后面

  • 書寫sql語句時,盡量避免造成索引失效的情況

多表關聯查詢優化策略
  • 保證被驅動表的join字段已經被索引

  • left join 時,選擇小表作為驅動表,大表作為被驅動表。

  • inner join 時,mysql會自己幫你把小結果集的表選為驅動表。

  • 子查詢盡量不要放在被驅動表,有可能使用不到索引。

  • 能夠直接多表關聯的盡量直接關聯,不用子查詢。

子查詢優化
  • 盡量不要使用not in或者not exists。用left outer join on xxx is null 替代。

排序分組優化
  • ORDER BY子句,盡量使用Index方式排序,避免使用FileSort方式排序

  • 當范圍條件是group by 或者 order by 的字段出現二選一時 ,優先觀察條件字段的過濾數量,如果過濾的數據足夠多,而需要排序的數據并不多時,優先把索引放在范圍字段上。反之,亦然。

  • 如果不在索引列上,filesort有兩種算法:
    mysql就要啟動雙路排序和單路排序

  • GROUP BY關鍵字優化

group by 使用索引的原則幾乎跟order by一致 ,唯一區別是groupby 即使沒有過濾條件用到索引,也可以直接使用索引。


本文簡單總結了下MySQL常見常用的索引優化策略


—END—

分享知識|一起成長


【DragonWell】

總結

以上是生活随笔為你收集整理的mysql单列索引和多列索引_浅谈MySQL索引优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。