查找学校是北大的学生信息

43 阅读3分钟

描述

题目:现在运营想要筛选出所有北京大学的学生进行用户调研,请你从用户信息表中取出满足条件的数据,结果返回设备id和学校。

示例:user_profile

iddevice_idgenderageuniversityprovince
12138male21北京大学Beijing
23214male复旦大学Shanghai
36543female20北京大学Beijing
42315female23浙江大学ZheJiang
55432male25山东大学Shandong

根据示例,你的查询应返回以下结果:

device_iduniversity
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|北京大学

解题

原题

image.png

索引覆盖

加入索引后运行时间有所优化,但内存消耗略增加

image.png

小结

覆盖索引

原理:就是查询字段在 二级索引中全部找到,不需要回表查询

覆盖索引只是特定于具体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行,从而可以减少比较的次数,大幅度提高查询的效率。