MySQL查询建议 - 列与联合

时间:2017-07-13 07:11:34

标签: mysql performance join left-join

我们有一个这样的用户表 - 超过2000万条目。

CREATE TABLE `users` (
  `uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(64) default '',
  `email` varchar(64) default '',
  `flag` int(10) unsigned DEFAULT '0',
  PRIMARY KEY (`uid')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

在我们的管理面板中,我们希望从用户表中显示一些固定用户和搜索结果。

我们认为有两种方法可以显示固定用户(请提示是否有其他更好的方法)

1)在用户表中为固定用户添加单独的列。但是,与用户总数(> 20M)相比,固定用户少数(少于100)。因此,这种方法看起来并不乐观。

2)一个固定用户和使用连接的单独表格,

CREATE TABLE `pinnedusers` (
  `uid` int(10) unsigned NOT NULL default 0,
   PRIMARY KEY (`uid`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

并运行联接,例如,

select * 
from users 
left join pinnedusers 
    on pinnedusers.uid=users.uid 
order by pinnedusers.uid desc 
limit 200;

然而,我们担心第二种方法的表现,因为它涉及加入,订单,限制。

你有什么建议?

2 个答案:

答案 0 :(得分:0)

这应该产生你想要的结果,并指出哪些行是"固定"用户。

SELECT 
    a.*,
    IF(b.`id` IS NULL,0,1) as `is_pinned`
FROM users a
LEFT JOIN pinnedusers b
    on b.uid = a.uid 
ORDER BY IF(b.`id` IS NULL,0,1) DESC, a.uid DESC
LIMIT 200;

答案 1 :(得分:0)

恐怕不是JOIN,而是需要扫描整个20M行。

要“显示一些固定用户”,请使用此选项“最多显示200个固定用户”:

SELECT u.*
    FROM pinnedusers p
    JOIN users u  USING(uid)
    ORDER BY ...
    LIMIT 200;

如果固定用户少于200个,则列表将少于200个。但查询速度会很快。

您的原始查询和Sloan都非常慢,因为他们必须扫描整个20M行(假设固定少于200行)。

如果您希望所有固定用户加上足够的非固定用户填写200的列表,那就是另一项任务。但是,您想要哪些非固定用户?前几个?那会很快。一个随机的几个?这更复杂,否则它也会扫描整个20M。其他一些标准?