我有一个非常简单的查询来获得一个玩家和他的朋友,但它似乎做了一个全表扫描,我没有看到它的原因。我是否需要将其重写为连接以使其使用索引?播放器表有7411行。
SQL:
SELECT id, credits, name, image_url FROM player WHERE ID = '999'
or ID in(select friend_id from player_friends where player_id = '999')
解释:
'1','PRIMARY','player','ALL','PRIMARY',NULL,NULL,NULL,'6994','Using where'
'2','DEPENDENT SUBQUERY','player_friends','ref','index2','index2','198','const,func','1','Using where; Using index'
架构:
CREATE TABLE `player` (
`ID` varchar(32) NOT NULL,
`Name` varchar(45) DEFAULT NULL,
`Credits` decimal(12,3) DEFAULT NULL,
`Access_token` varchar(255) DEFAULT NULL,
`Registered` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`Image_url` varchar(500) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
CREATE TABLE `player_friends` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`player_id` varchar(32) DEFAULT NULL,
`friend_id` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `index2` (`player_id`,`friend_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
答案 0 :(得分:1)
首先,编写查询以使用exists
:
SELECT id, credits, name, image_url
FROM player p
WHERE ID = '999' OR
EXISTS (select 1
from player_friends pf
where pf.player_id = '999' and pf.friend_id = p.id
);
这可能会更有效率。如果它不能满足您的需求,请考虑将其分为两个查询:
SELECT id, credits, name, image_url
FROM player p
WHERE ID = '999'
UNION
SELECT id, credits, name, image_url
FROM player p
WHERE EXISTS (select 1
from player_friends pf
where pf.player_id = '999' and pf.friend_id = p.id
);
请注意使用UNION
删除重复项。
答案 1 :(得分:0)
尝试加入:
SELECT p1.id, p1.credits, p1.name, p1.image_url
FROM player p1
LEFT JOIN player_friends pf ON pf.player_id = p1.id
WHERE p1.id = '999' OR pf.friend_id = '999'