【SQL 必知必會】性能篇 05. 深入淺出索引(二)如何通過索引讓SQL 查詢效率最大化?

上一篇 深入淺出索引(一),我們講到了索引的基本概念,通過索引可以提高我們的查詢效率,同時學習了索引的常用模型,索引的種類,在數據量少的時候,以及數據量重複度高的情況下不適合使用索引。今天我們學習一下通過索引如何讓查詢效率最大化,到底什麼情況下使用索引。

  • 數據表字段具有哪些特徵時,使用索引呢?
  • 索引失效的情況有哪些,如何避免?

1. 具體情況下使用索引呢

1.1 字段具有唯一性的限制,比如身份證號

上一篇文章我們講述的索引的種類,例如唯一索引,主鍵索引,這些所有具有唯一性約束,如果數據表中的字段具有唯一性,我們就可以對該字段創建唯一索引,或者主鍵索引。

1.2 海量數據情況下,WHERE 後面篩選過濾的字段

我們從一個具有一百萬條的數據表中,根據user_id 查詢用戶姓名。

select user_name from user_gender where user_id=10999

user_id 字段不加索引的情況,查詢一條記錄表需要的時間爲0.167s
在這裏插入圖片描述
user_id 字段加索引的情況,查詢所花費的時間是原來的十分之一,可怕吧!
在這裏插入圖片描述

1.3. GROUP BY 和 ORDER BY 的列

只有一個查詢條件的情況

我們昨天講到了聚集索引,聚集索引的數據表存儲數據在物理上是按順序存放的,加索引也是讓數據按照某種順序存放,通過索引,可以減少 group by 和 order by 的工作量。這樣可以提高查詢效率。

查詢 用戶ID 和 用戶姓名 ,並根據用戶ID進行分組,顯示數量爲100.

SELECT  user_id, count(user_gender) as num FROM user_gender group by user_id limit 100

group by 後面字段爲user_id ,不加索引的情況,我們發現獲取這100 條數據花費的時間爲0.398秒。
在這裏插入圖片描述
對user_id 添加索引後,發現查詢時間 僅爲原來的30分之一。可見在group by 字段後面加索引能提高查詢效率。
在這裏插入圖片描述
查詢條件增多的情況

如果我們對上述分組的數據按照性別數量進行降序排序(此時既有分組,也有排序,查詢條件增多)

SELECT  user_id, count(user_gender) as num FROM user_gender group by user_id  order by num desc limit 100 

如果只對 group by 後面的user_id 加索引,花費的時間爲 0.564 s。
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200406105320376.png
同時對 group by後面的字段 user_id 和 order by 後面的字段 user_gender 加索引,此時爲兩個單列索引。花費的時間爲0.625s ,可見當有多個查詢條件是,單個索引的效率和多個索引的效率沒有差別,也就是說此時只有一個索引生效,mysql 數據庫會選擇限制最嚴的作爲索引。
在這裏插入圖片描述

** 1.4 聯合索引**

上述我們發現當查詢條件增多的時候,創建單個索引和創建多個索引的效率基本沒有發生變化,也就意味着索引只是生效了一個。如果我們創建聯合索引呢。

我們創建對user_id 和user_gender兩列創建聯合索引,聯合索引順序爲 user_gender user_id ,查詢數據所花費的時間爲0.371s.
在這裏插入圖片描述
如果聯合索引的順序爲 user_id 和 user_gender ,查詢時間爲0.177秒 ,可見創建聯合索引的順序對查詢效率也要一定的影響。
在這裏插入圖片描述
兩個單列索引花費的時間爲 0.625s ,聯合索引花費的時間爲0.177s ,可見聯合索引的效率還是很高的,注意,聯合索引創建的順序,對查詢效率有一定的影響。且使用聯合索引要符合最左匹配原則,否則索引會失效,上一篇我們進行了詳細的介紹。

1.5. DISTINCT 修飾的字段需要加索引

DISTINCT 用來對數據表字段進行去重,對DISTINCT 修飾的字段加索引可以提高查詢效率。

SELECT DISTINCT(user_gender) FROM user_gender

對 user_gender 字段不加索引,花費的時間爲 0.178s。
在這裏插入圖片描述
對 user_gender 字段不加索引,花費的時間爲0.026s。時間僅爲原來的七分之一。
在這裏插入圖片描述
1.6. 多表JOIN 連接操作

對於數據表而言,數據表數量控制三張表以內。
對於SQL語句而言,儘量大可能的篩選字段。
對於數據表字段而言,數據表之間連接,儘量保持連接字段的數據類型一致。

2. 索引經常會失效,請注意

2.1 對索引字段進行表達式運算,索引會失效

select user_name from user_gender where user_id +1 =10999

在這裏插入圖片描述
如果我們對user_id 字段加索引後並對其進行表達式計算,我們發現查詢時間增加將近原來的10倍
執行查詢計劃,發現索引失效,也就是或當我們對索引字段進行表達式計算,索引會失效。
在這裏插入圖片描述
2.2 對索引進行函數操作,索引會失效。

2.3 使用 LIKE 模糊查詢,後面不能是 %,但是可以是a%**

2.4 where 語句中後面條件使用了OR 邏輯運算符,如果OR前的字段進行了索引,後面字段沒加索引,則索引失效。

此時我們只對 user_id 加索引。

select user_id,user_gender from user_gender where user_id >=10991 or user_gender=1

執行SQL語句我們發現,查詢時間爲 0.203s。OR是或者的意思,滿足一個條件即可,如果只是加一條索引,那麼另一條就沒有任何意義了,此時會進行全表掃描。
在這裏插入圖片描述
執行查詢計劃發現索引失效
在這裏插入圖片描述
2.5 索引列儘量設置爲 不爲空,可以將INT類型默認值設置爲0 ,字符串類型默認設置爲空字符串(‘’)

總結:上述我們介紹了什麼情況下使用索引,什麼情況使用索引,索引會失效。這樣的好東西,你學會了麼?

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