描述
题目:现在运营想要筛选出所有北京大学的学生进行用户调研,请你从用户信息表中取出满足条件的数据,结果返回设备id和学校。
示例:user_profile
id | device_id | gender | age | university | province |
---|---|---|---|---|---|
1 | 2138 | male | 21 | 北京大学 | Beijing |
2 | 3214 | male | 复旦大学 | Shanghai | |
3 | 6543 | female | 20 | 北京大学 | Beijing |
4 | 2315 | female | 23 | 浙江大学 | ZheJiang |
5 | 5432 | male | 25 | 山东大学 | Shandong |
根据示例,你的查询应返回以下结果:
device_id | university |
---|---|
2138 | 北京大学 |
6543 | 北京大学 |
示例
输入:
drop table if exists user_profile;
CREATE TABLE `user_profile` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`gender` varchar(14) NOT NULL,
`age` int ,
`university` varchar(32) NOT NULL,
`province` varchar(32) NOT NULL);
INSERT INTO user_profile VALUES(1,2138,'male',21,'北京大学','BeiJing');
INSERT INTO user_profile VALUES(2,3214,'male',null,'复旦大学','Shanghai');
INSERT INTO user_profile VALUES(3,6543,'female',20,'北京大学','BeiJing');
INSERT INTO user_profile VALUES(4,2315,'female',23,'浙江大学','ZheJiang');
INSERT INTO user_profile VALUES(5,5432,'male',25,'山东大学','Shandong');
输出:
2138|北京大学
6543|北京大学
解题
原题
索引覆盖
加入索引后运行时间有所优化,但内存消耗略增加
小结
覆盖索引
原理:就是查询字段在 二级索引中全部找到
,不需要回表查询
覆盖索引
只是特定于具体select语录而言的联合索引。也就是说一个联合索引对于某个select语句,通过索引可以直接获取查询结果,而不再需要回表查询啦,就称该联合索引覆盖了这条select语句。
题解
添加device_id = user_profile.device_id
的条件,每次查询时会多比较一次。但是这种比较方式可以大幅度缩小数据集的范围,从而提高整个查询的效率。
当使用
where university = "北京大学"
这个条件进行查询时,如果这个列上没有建立索引,那么查询需要对所有的
university
列的值进行比较,来找出所有符合条件的记录。当找到满足
university = "北京大学"
这个条件的记录时,还需要对
device_id
列的值进行比较,才能确定哪些行是我们要查找的数据。
而如果条件改为
where university = "北京大学" and device_id = user_profile.device_id
,那么查询引擎会优先使用建立在
device_id
列上的索引进行查询,只查询符合
university = "北京大学"
条件的那些行,并且这些行的
device_id
字段必须和行本身的设备ID相等。
假设有一个数据集包含1000行,其中只有10行满足
university = "北京大学"
的条件。
如果只使用
university = "北京大学"
这个条件,则在比较完这1000行中所有符合条件的行后,还需根据每个符合条件的行的设备ID来进行一次比较。而通过添加
device_id = user_profile.device_id
这个条件,我们每次只比较满足
university = "北京大学"
的那10行,从而可以减少比较的次数,大幅度提高查询的效率。