视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
MySQL查询优化:用子查询代替非主键连接查询实例介绍_MySQL
2020-11-09 18:56:56 责编:小采
文档


bitsCN.com 一对多的两张表,一般是一张表的外键关联到另一个表的主键。但也有不一般的情况,也就是两个表并非通过其中一个表的主键关联。
例如:

create table t_team
(
tid int primary key,
tname varchar(100)
);
create table t_people
(
pid int primary key,
pname varchar(100),
team_name varchar(100)
);

team表和people表是一对多的关系,team的tname是唯一的,people的pname也是唯一的,people表中外键team_name和team表的tname关联,并不是和主键id关联。
(PS:先不说这样的设计合不合理,但如果真的摊上这事儿…..很多表的设计是每个表有一个id和uuid,id作为主键,uuid作关联,和上面情况类似)
现在要查询pname是"xxg"的people和team信息:
SELECT * FROM t_team t,t_people p WHERE t.tname=p.team_name AND p.pname='xxg' LIMIT 1;

SELECT * FROM t_team t INNER JOIN t_people p ON t.tname=p.team_name WHERE p.pname='xxg' LIMIT 1;
执行一下,可以查询出结果,但是如果数据量大的情况下,效率很低,执行很慢。
对于这种连接查询,用子查询来代替,查询结果相同,但会效率更高:
SELECT * FROM (SELECT * FROM t_people WHERE pname='xxg' LIMIT 1) p, t_team t WHERE t.tname=p.team_name LIMIT 1;
子查询中过滤了大量的数据(仅保留一条),再将结果来连接查询,效率会大大提高。
(PS:另外,使用LIMIT 1也可以提高查询效率,详细:http://blog.csdn.net/xiao__gui/article/details/8726272 )
本人通过3条SQL测试两种查询方式的效率:
准备1万条team数据,准备100万条people数据。
造数据的存储过程:

BEGIN
DECLARE i INT;
START TRANSACTION;
SET i=0;
WHILE i<10000 DO
INSERT INTO t_team VALUES(i+1,CONCAT('team',i+1));
SET i=i+1;
END WHILE;
SET i=0;
WHILE i<1000000 DO
INSERT INTO t_people VALUES(i+1,CONCAT('people',i+1),CONCAT('team',i%10000+1));
SET i=i+1;
END WHILE;
COMMIT;
END

SQL语句执行效率:
连接查询

SELECT * FROM t_team t,t_people p WHERE t.tname=p.team_nameAND p.pname='people20000' LIMIT 1;

Time:12.594 s
连接查询

SELECT * FROM t_team t INNER JOIN t_peoplep ON t.tname=p.team_name WHERE p.pname='people20000' LIMIT 1;

Time:12.360 s
子查询

SELECT * FROM (SELECT * FROM t_people WHEREpname='people20000' LIMIT 1) p, t_team t WHERE t.tname=p.team_name LIMIT 1;

Time:0.016 sbitsCN.com

下载本文
显示全文
专题