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 若至少有一列的索引不是等值查詢,此時將