1. 程式人生 > >mysql 索引實踐(一) 單個索引

mysql 索引實踐(一) 單個索引

#emp_no   PRIMARY
#first_name
#last_name

show index from employees

#等值查詢 =

#範圍查詢 in

#字首匹配 like 'xx%'

#不等值查詢 !=、>、>=、<、<=、not like、not in、like '%xx'、is not null

 

需要注意:

即使在使用了不等值查詢、使用了 is null、is not null 、OR, 也不能說該查詢一定不走索引。

#若where存在非索引的列並使用了OR,則一定是全表掃描#

 

聚集索引(葉子節點存放行記錄資料)

#const
explain select * from employees where emp_no = 10001
#range    

#Using where
explain select * from employees where emp_no !=  10001

#const    
explain select * from employees where birth_date = '1953-09-02' and emp_no =  10001

#range    
#Using where
explain select * from employees where birth_date = '1953-09-02' and emp_no !=  10001

#無論存在多少個其他非索引的列的條件,即使其他列使用了非等值查詢、is NOT NULL、not Like、not in等,存在聚集索引時,都是先根據主鍵進行查詢出相關記錄,再根據條件過濾#

#1.即使存在多個索引索引,當主鍵匹配為等值匹配,則優先使用聚集索引#
explain select * from employees where first_name =  'Georgi' and last_name =  'Facello' and emp_no =  10001

#2.若主鍵匹配不為等值匹配,將優先使用其他等值匹配的索引索引.
#2.1.此時,優先使用first_name輔助索引
explain select * from employees where first_name =  'Parto1' and emp_no !=  10001

#2.2.此時,優先使用last_name輔助索引
explain select * from employees where first_name !=  'Georgi' and last_name =  'Facello' and emp_no !=  10001

#3.若不存在其他等值匹配的輔助索引,則將使用聚集索引
explain select * from employees where first_name !=  'Georgi' and last_name !=  'Facello' and birth_date = '1953-09-02' and emp_no !=  10001

輔助索引(葉子節點不存放行記錄資料)

單個輔助索引:

#ref
explain select * from employees where first_name =  'Parto1'

#字首字串匹配 range
#Using index condition
explain select * from employees where first_name like  'Parto1%'

#非等值查詢均為:
#all
#Using where
explain select * from employees where first_name !=  'Parto1'
explain select * from employees where first_name like  '%Parto1'
explain select * from employees where first_name like  '%Parto1%'
explain select * from employees where first_name not like  'Parto1%'
explain select * from employees where first_name is not null

#ref
#Using where
explain select * from employees where birth_date = '1953-09-02' and first_name =  'Parto1'

#all
#Using where
explain select * from employees where birth_date = '1953-09-02' and first_name !=  'Parto1'

#單個輔助索引,只要不是等值查詢或字首字串匹配,均將進行全表掃描#

#單個輔助索引和聚合索引一起時:
#1.若聚合索引為等值查詢,則優先使用聚合索引;
#2.若聚合索引為不等值查詢,當前輔助索引為等值查詢,則使用當前輔助索引;
#3.若當前輔助索引也為不等值查詢,則仍使用聚合索引.

 

多個輔助索引:

#index_merge(使用了idx_last_name,idx_first_name)
#Using intersect(idx_last_name,idx_first_name); Using where
explain select * from employees where first_name =  'Saniya' and last_name = 'Bamford'

#range
#Using index condition; Using where; Using MRR
explain select * from employees where first_name =  'Saniya' and last_name like 'Bamfo%'

#range
#Using index condition; Using where; Using MRR
explain select * from employees where first_name like  'Sani%' and last_name like 'Bamfo%'

#index_merge
#Using intersect(idx_last_name,idx_first_name); Using where
explain select * from employees where first_name =  'Saniya' and last_name = 'Bamford' and birth_date = '1953-09-02'

#ref (使用了idx_first_name)
#Using where
explain select * from employees where first_name =  'Saniya' and last_name != 'Bamford'

#all
#Using where
explain select * from employees where first_name !=  'Patricio' and last_name != 'Bamford'

#all
#Using where
explain select * from employees where first_name !=  'Patricio' and last_name is not null

#對於非等值查詢的輔助索引,此時該列和不是索引的列查詢結果,並無二異.


#index_merge
#Using union(idx_first_name,idx_last_name); Using where
explain select * from employees where first_name =  'Saniya' OR last_name = 'Bamford'

#ALL
#Using where
explain select * from employees where first_name =  'Saniya' OR last_name != 'Bamford'

#ALL
#Using where
explain select * from employees where first_name =  'Saniya' OR last_name = 'Bamford' OR birth_date = '1953-09-02'

#使用OR連線時:
#1.1 當所有的列均為索引,且為等值查詢,仍將採用index_merge 進行查詢
#1.2 若有一列不是索引,此時將全表掃描;
#1.3 若至少有一列的索引不是等值查詢,此時將