我很难在这个问题上获得更好的结果:
我有以下2个表格:
DROP TABLE IF EXISTS `casino`.`mutualfriends`;
CREATE TABLE `casino`.`mutualfriends` (
`CustUID` varchar(64) CHARACTER SET ascii NOT NULL,
`CustUID2` varchar(64) CHARACTER SET ascii NOT NULL,
`FType` tinyint(4) NOT NULL,
PRIMARY KEY (`CustUID`,`CustUID2`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `casino`.`customers`;
CREATE TABLE `casino`.`customers` (
`CustFullName` varchar(45) NOT NULL,
`CustEmail` varchar(128) NOT NULL,
`CustUID` varchar(64) CHARACTER SET ascii NOT NULL,
`CustMoney` bigint(20) NOT NULL DEFAULT '0',
`SmallPicURL` varchar(120) CHARACTER SET ascii DEFAULT '',
`LargePicURL` varchar(120) CHARACTER SET ascii DEFAULT '',
PRIMARY KEY (`CustUID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
customers表有1M行,共有朋友有500K行。
我很难优化这个查询;似乎有一个表扫描使用它。我想尽量减少扫描:
SELECT c.CustUID AS Cuid, c.CustFullName, c.CustMoney, c.SmallPicURL
FROM `customers` c
WHERE c.`CustUID` = '1:1542073175'
UNION
SELECT m.`CustUID2` AS Cuid, c.CustFullName, c.CustMoney, c.SmallPicURL
FROM `mutualfriends` m, `customers` c
WHERE m.`CustUID` = '1:1542073175'
AND c.`CustUID` = m.`CustUID2`
UNION
SELECT m.`CustUID` AS Cuid, c.CustFullName, c.CustMoney, c.SmallPicURL
FROM `mutualfriends` m, customers c
WHERE m.`CustUID2` = '1:1542073175'
AND c.CustUID = m.`CustUID`
答案 0 :(得分:2)
我认为你需要MutualFriends.CustUID2的索引(重复索引,不是唯一索引;而不是主键的一部分)。主键可能为您首先列出已识别客户('1:1542073175')的查询提供可用索引。
检查查询计划的说明。
我认为你对UNION的第三部分进行顺序扫描是正确的,也可能是第二部分。
答案 1 :(得分:0)
尝试此查询
SELECT c.CustUID AS Cuid, c.CustFullName, c.CustMoney, c.SmallPicURL
FROM `customers` c INNER JOIN `mutualfriends` m
IN c.CustUID = m.`CustUID`
WHERE m.`CustUID2` = '1:1542073175'
答案 2 :(得分:0)
尝试使用此查询:
select *
from customers
where CustUID in (
select CustUID
from mutual_friends
where CustUID2 = '1:1542073175'
union all
select CustUID2
from mutual_friends
where CustUID = '1:1542073175'
union all
select '1:1542073175'
)
那更快吗?