需求:获取某个人的粉丝信息
相关表结构:
CREATE TABLE `auth_user` (
`id` int NOT NULL AUTO_INCREMENT,
`password` varchar(128) NOT NULL,
`last_login` datetime(6) DEFAULT NULL,
`is_superuser` tinyint(1) NOT NULL,
`username` varchar(150) NOT NULL,
`first_name` varchar(150) NOT NULL,
`last_name` varchar(150) NOT NULL,
`email` varchar(254) NOT NULL,
`is_staff` tinyint(1) NOT NULL,
`is_active` tinyint(1) NOT NULL,
`date_joined` datetime(6) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `friendships_friendship` (
`id` bigint NOT NULL AUTO_INCREMENT,
`created_at` datetime(6) NOT NULL,
`from_user_id` int DEFAULT NULL,
`to_user_id` int DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `friendships_friendship_from_user_id_to_user_id_c3116feb_uniq` (`from_user_id`,`to_user_id`),
KEY `friendships_friendship_to_user_id_986baf39_fk_auth_user_id` (`to_user_id`),
CONSTRAINT `friendships_friendship_from_user_id_ca1edd7e_fk_auth_user_id` FOREIGN KEY (`from_user_id`) REFERENCES `auth_user` (`id`),
CONSTRAINT `friendships_friendship_to_user_id_986baf39_fk_auth_user_id` FOREIGN KEY (`to_user_id`) REFERENCES `auth_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
下面两种 sql 哪种效率更高?
方式一:
SELECT
`friendships_friendship`.`id`,
`friendships_friendship`.`from_user_id`,
`friendships_friendship`.`to_user_id`,
`friendships_friendship`.`created_at`,
T3.`id`,
T3.`password`,
T3.`last_login`,
T3.`is_superuser`,
T3.`username`,
T3.`first_name`,
T3.`last_name`,
T3.`email`,
T3.`is_staff`,
T3.`is_active`,
T3.`date_joined`
FROM
`friendships_friendship`
LEFT OUTER JOIN `auth_user` T3 ON (
`friendships_friendship`.`from_user_id` = T3.`id`
)
WHERE
`friendships_friendship`.`to_user_id` = 1
LIMIT
21;
方式二:
先获取所有 id
SELECT
`friendships_friendship`.`id`,
`friendships_friendship`.`from_user_id`,
`friendships_friendship`.`to_user_id`,
`friendships_friendship`.`created_at`
FROM
`friendships_friendship`
WHERE
`friendships_friendship`.`to_user_id` = 1
LIMIT
21;
把这些 id 作为第二次查询的 from_user_id 使用 in 操作符 select
SELECT
T3.`id`,
T3.`password`,
T3.`last_login`,
T3.`is_superuser`,
T3.`username`,
T3.`first_name`,
T3.`last_name`,
T3.`email`,
T3.`is_staff`,
T3.`is_active`,
T3.`date_joined`
FROM
`auth_user` T3
WHERE
T3.`from_user_id` in (xxxx, xxx, xxxx)
LIMIT
21;
mysql 对于有 join 的 select 是先执行 where 还是 join?
比如对于方式一,mysql 是先 LEFT OUTER JOIN auth_user T3 ON (friendships_friendship.from_user_id = T3.id)
还是先 friendships_friendship.to_user_id = 1
?
我的表都是空的
执行计划:
第一种方式效率会更高,毕竟只执行了一次sql,虽然使用了join操作,但只会将满足条件的记录进行join操作,跟第二种方式使用in不会有太大差别。
对于方式一,先会找到to_user_id=1的数据,再进行join操作