mysql 索引-【應用】

在對B樹和B+樹進行了一定的瞭解之後,終於耐住性子過來對Mysql索引進行一定的總結。本篇我們暫不提原因,僅僅通過SQL執行來對索引進行一定的總結。
索引到底是什麼?其本質其實就是數據結構,能夠幫助我們快速的獲取數據庫中的數據。

導入測試庫:

測試數據庫:mysql官方Employee數據;也可以在我的共享雲盤中下載:鏈接:https://pan.baidu.com/s/1b-0EtvTxbTQPRNK7HkaQag 密碼:64oh
下載完成之後,操作命令,導入到數據庫中。在導入的過程中,遇到如下錯誤:導入不成功
當執行source /Users/huoyajing/kupai-worker/software/mysql/employees_db/employees.sql時,導入錯誤,提示“Failed to open file ‘load_employees.dump’,error:2”,說明找不到,我們可以編輯employees.sql加入全路徑,如下圖:
employees.sql
導入成功之後,我們則正是開啓索引總結。

唯一索引:

查看唯一索引效率,我們首先要開啓性能分析功能:

//查看是否打開了性能分析列表;
select @@profiling;  

select @@profiling

// 打開 profiling 功能
set profiling=1; 

set profiling

//再無索引情況下執行語句
select * from employees where first_name = 'Chirstian';
//爲first_name加上索引
alter table employees add index first_name (first_name);
//加入索引之後再次執行
select * from employees where first_name = 'Chirstian';

如下爲性能分析結果:
分析結果
通過紅色標記可發現,加入索引之後,性能提高了50倍之多,可見索引的速度之快。

聯合索引:

聯合索引遵循原則:最左前綴匹配原則
這裏說明一下explain幾個關鍵字段的含義

字段 說明
id 這是SELECT的查詢序列號
select_type select_type就是select的類型;SIMPLE:簡單SELECT(不使用UNION或子查詢等)
type 有無使用索引 結果值從好到壞依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL(若索引在range之外,則證明索引無啥效果,性能很差)
possible_keys 顯示MySQL可能決定使用的鍵(索引)
key 顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL
rows 顯示MySQL認爲它執行查詢時必須檢查的行數
filtered 顯示了通過條件過濾出的行數的百分比估計值

接下來我們對(birth_date, first_name, last_name)創建一個聯合索引:

alter table employees add index bd_fn_ln (birth_date, first_name, last_name);

分別執行以下SQL:

  1. select * from employees where birth_date = ‘1954-05-01’ and first_name = ‘Chirstian’ and last_name = ‘Koblick’;
    001
  2. select * from employees where birth_date = ‘1954-05-01’ and first_name = ‘Chirstian’ and last_name = ‘Koblick’;
    002
  3. select * from employees where birth_date = ‘1954-05-01’ and last_name = ‘Koblick’;
    003
  4. select * from employees where last_name = ‘Koblick’ and birth_date = ‘1954-05-01’;
    004
    注意:語句3和語句4其實是完全等效的,因爲並不符合最左前綴原則,所以只是birth_date索引生效,last_name索引並不生效。看語句3和語句4,explain執行的rows字段,值爲60,其實就是在對birth_date進行插入之後,查詢出的條數爲60條,然後再從60條內挑選last_name = ‘Koblick’的數據。
    看根據birth_date查詢條數:
    0001
  5. select * from employees where first_name = ‘Chirstian’ and last_name = ‘Koblick’;
    10
    看紅色標記部分,因爲以上我們見了一個firse_name唯一索引,和一個三個字段的聯合索引,此語句根據first_name和last_name查詢,因爲並非是符合最左前綴原則,所以並沒有用到聯合索引,僅僅是使用了我們建的唯一索引值,rows爲226,filtered爲10.00證明根據firse_name查詢出的結果爲226行,通過firse_name查詢過濾出的行數佔比10%左右。
    11
    同樣執行語句5,但是把唯一索引去除,看explain執行結果:
    12
    並無用到索引。效率很慢。

索引使用注意項:

  • 選擇區分度高列作爲索引,區分度是一個介於0和1之間的小數,越接近1區分度越高,越適合做索引。什麼意思呢,就是說比如男女字段,只有男女兩個值,並不是適合做索引,但是比如地名,通訊錄,從a-z;又或者一個公司中,每個員工有一個工號,用工號做索引,那麼區分度就是1,用工號做索引就非常有效。
  • 唯一索引和主鍵索引區別:unique index值必須是唯一的,但是有且可以有多個NULL值;而primary key,值也必須是唯一的,其唯一區別是primary是不能有NULL值的。對於主鍵也是可以做聯合索引的,其實意思就是本條記錄用一個字段作爲主鍵是不能確保唯一的,比如我用A和B都作爲主鍵,兩個聯合到一起就是所謂的聯合主鍵。
  • 導致索引失效的幾種常出現的情況:
    -查詢條件使用函數在索引列上,或者對索引列進行運算,運算包括(+,-,*,/,! 等)都會導致索引失效;
    -如果條件中有or,要想索引失效,則必須讓or的所有字段都加上索引;
    -like查詢是以%開頭(如圖是%開頭和結果的兩種結果)
    111
    -如果列類型是字符串,那一定要在條件中將數據使用引號引用起來;
    -字符型字段爲數字時在where條件裏不添加引號;
    -not in ,not exist;(唯一索引失效)
    13
    -B+索引中,is null索引失效;is not null索引生效;
    14

索引講述到此,下篇則主要針對原理進行一下講解。

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