复合索引&最左原则 -- 实战

建表语句:

CREATE TABLE `t_user` (
	`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
	`bu_id` INT(20) NOT NULL,
	`name` VARCHAR(255) NOT NULL,
	`age` INT(11) NOT NULL,
	`sex` VARCHAR(255) NULL DEFAULT NULL,
	PRIMARY KEY (`id`),
	INDEX `index_uid_name_age` (`bu_id`, `name`, `age`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=22014
;

批量插入数据:

CREATE PROCEDURE batch_insert() 
BEGIN 
	DECLARE a INT DEFAULT 1; 

	WHILE (a <= 10000) DO 
	SET a = a + 1; 
	insert into t_user set name='name2', age=a, bu_id=a+5;
	END WHILE;

	COMMIT;
END;
CALL batch_insert();

**Explain SQL: **

Explain SQL- 图示

Explain SQL:

1)explain select bu_id,name,age,sex from t_user where bu_id=17
  
	  结果:id	select_type	 table	type	possible_keys			key						key_len	 ref	rows 
			1	SIMPLE		 t_user	ref		index_buid_name_age		index_buid_name_age		4		 const	10853	
	  结论:使用了index_buid_name_age索引,并且只使用了复合索引中的bu_id列。
		
2)explain select bu_id,name,age,sex from t_user where name='jack'
	
	  结果:id	select_type	 table	type	possible_keys			key 					key_len  ref	rows	Extra 
			1	SIMPLE		 t_user	ALL																		21706	Using where
	  结论:没有使用索引,进行了全表扫描。
	
3)explain select bu_id,name,age,sex from t_user where bu_id=17 and name='jack'
	
	  结果:id	select_type	 table	type	possible_keys			key 					key_len  ref			rows	Extra 
			1	SIMPLE		 t_user	ref		index_buid_name_age		index_buid_name_age		771		 const,const	1		Using index condition
			
	  结论:使用了index_buid_name_age索引,并且(根据key_len可以推断出)使用了该复合索引中的bu_id列和name列。
	
4)explain select bu_id,name,age,sex from t_user where bu_id=17 and name='jack' and age=18

	  结果:id	select_type	 table	type	possible_keys			key 					key_len  ref				rows	Extra 
			1	SIMPLE		 t_user	ref		index_buid_name_age		index_buid_name_age		775		 const,const,const	1		Using index condition
			
	  结论:使用了index_buid_name_age索引,并且(根据key_len可以推断出)使用了该复合索引中的bu_id列、name列和age列。

5)explain select bu_id,name,age,sex from t_user where bu_id=17 and name like '%jack'

	  结果:id	select_type	 table	type	possible_keys			key 					key_len  ref			rows	Extra 
			1	SIMPLE		 t_user	ref		index_buid_name_age		index_buid_name_age		4		 const			10853	Using index condition
	  结论:使用了index_buid_name_age索引,但是只使用了该复合索引中的bu_id列。
  
6)explain select bu_id,name,age,sex from t_user where bu_id=17 and name like 'jack%'
 
	  结果:id	select_type	 table	type	possible_keys			key 					key_len  ref			rows	Extra 
			1	SIMPLE		 t_user	range	index_buid_name_age		index_buid_name_age		771						1		Using index condition
	  结论:使用了index_buid_name_age索引,并且(根据key_len可以推断出)使用了该复合索引中的bu_id列和name列。
  
7)explain select bu_id,name,age,sex from t_user where bu_id=17 and age=18
  
	  结果:id	select_type	 table	type	possible_keys			key 					key_len  ref			rows	Extra 
			1	SIMPLE		 t_user	ref		index_buid_name_age		index_buid_name_age		4		 const			10852	Using index condition
	  结论:使用了index_buid_name_age索引,但是只使用了该复合索引中的bu_id列。
  
8)explain select name from t_user where name='jack' 	或	explain select bu_id,name,age from t_user where name='jack'
  
	  结果:id	select_type	 table	type	possible_keys			key 					key_len  ref			rows	Extra 
			1	SIMPLE		 t_user	index							index_buid_name_age		775						21705	Using where; Using index
	  结论:使用了index_buid_name_age索引,并且(根据key_len可以推断出)使用了该复合索引中的bu_id列、name列和age列。
	  注意:比较一下第2个sql语句和第8个sql语句,二者的区别在于:
			1>第2个sql语句查询了非索引列sex,故根据最左原则,无法使用该索引;
			2>第8个sql语句只查询了索引列,(若只查询索引列,则只需扫描索引树即可)故可以使用该索引。

猜你喜欢

转载自my.oschina.net/u/1399755/blog/1787166