小表内连接大表,如何加快

Posted

技术标签:

【中文标题】小表内连接大表,如何加快【英文标题】:inner join large table with small table , how to speed up 【发布时间】:2010-11-30 11:23:57 【问题描述】:

亲爱的phpmysql专家 我有两张表,一张用于发布文章 200,000 条记录(索引列:sid),一张用于主题的小表(索引列 topicid)有 20 条记录。具有相同的 topicid

当前我正在使用:(花了大约 0.4 秒)

+从表中获取最后 50 条记录:

SELECT sid、aid、title、time、topic、informant、ihome、alanguage、counter、type、images、chainid FROMveryzoo_stories ORDER BY sid DESC LIMIT 0,50

+然后在每条记录中进行while循环,找到每条帖子的主题名称:

而(..) 从veryzoo_topics 中选择topicname,其中topicid='$topic'" ……

+现在 我打算使用 Inner Join 来加速过程,但作为我的测试,它需要更长的时间,从 1.5 秒到 3.5 秒

选择 a.sid、a.aid、a.title、a.time、a.topic、a.informant、a.ihome、a.alanguage、a.counter、a.type、a.images、a. chainid, t.topicname FROM veryzoo_stories a INNER JOIN veryzoo_topics t ON a.topic = t.topicid ORDER BY sid DESC LIMIT 0,50

看起来内部连接从两个表中全部连接了 200k 条记录,然后将结果限制在 50 .. 这花了很长时间..

请帮我指出正确的方法。 例如,从表 1 中取出最后 50 条记录。然后将其加入表 2 .. ect

【问题讨论】:

【参考方案1】:

不要不要使用内连接,除非两个表共享相同的主键,否则你会得到重复的值(当然还有一个较慢的查询)。

【讨论】:

nop 两个表没有相同的 p 键.. 大表 p 键是:sid 和小表的 topicid 为 p 键 我会使用 do while。除非满足某些条件,否则联接几乎不是加快查询速度的方法。 我不同意。进行 50 次查询将产生大量开销。使用连接(或带有 WHERE 的野蛮连接),将只有一个查询。 JOIn 语句已用于处理关系。如果数据库设计良好(带有索引和关系)并使用支持关系的现代引擎,性能应该会更好。 Join 语句的工作是在两个表之间创建记录的叉积,然后选择满足某些关系的出现,因此必须指定 good 关系,否则你会获取乘法值,或者根本没有值(取决于连接的类型)。抱歉,我的回答与问题无关(也有点不准确):我没有考虑加快查询速度,而是获得相同的结果。【参考方案2】:

请试试这个:

SELECT * 
FROM (
SELECT a.sid, a.aid, a.title, a.time, a.topic, a.informant, a.ihome, a.alanguage, a.counter, a.type, a.images, a.chainid
FROM veryzoo_stories a
ORDER BY sid DESC 
LIMIT 0 , 50
)b
INNER JOIN veryzoo_topics t ON b.topic = t.topicid

我做了一个小测试,它似乎更快。它使用子查询(嵌套查询)首先选择 50 条记录,然后加入。

还要确保veryzoo_stories.sid、veryzoo_stories.topic 和veryzoo_topics.topicid 是索引(如果您使用InnoDB,则该关系存在)。它应该会提高性能。

现在它留下了 ORDER BY LIMIT 的问题。它很重,因为它在选择之前订购了 200,000 条记录。我想这是必要的。使用 ORDER BY 时,索引非常重要。

这是一篇关于这个问题的文章:ORDER BY … LIMIT Performance Optimization

【讨论】:

感谢您的确认..看起来你的解决方案和我的一样..我坚持这个..非常感谢 好的。如果您有兴趣,我添加了一个关于 ORDER BY LIMIT 性能的有趣文章的链接。我提到的列是否有索引?您使用的是哪个后端(InnoDB、MyISAM)?无论如何,如果您认为该问题已得到解答,请选择一个答案(您的或我的)作为已接受。【参考方案3】:

我只是对嵌套查询 + 内连接进行测试,并惊讶于性能提高了很多:现在只需要 0.22s 。这是我的查询:

SELECT a.*, t.topicname 
FROM (SELECT sid, aid, title, TIME, topic, informant, ihome, alanguage, counter, TYPE, images, chainid 
  FROM  veryzoo_stories 
  ORDER BY sid DESC 
  LIMIT 0, 50) a 
  INNER JOIN veryzoo_topics t ON a.topic = t.topicid 

如果没有更多的解决方案出现,我可以使用这个.. 感谢任何人看这篇文章

【讨论】:

对不起,我没有看到答案。这正是我所做的。我认为这是正确的方法。 是否有veryzoo_stories.sid、veryzoo_stories.topic和veryzoo_topics.topicid的索引?这也可以提高性能。

以上是关于小表内连接大表,如何加快的主要内容,如果未能解决你的问题,请参考以下文章

在 Spark SQL 中将多个小表与大表连接的最佳方法

在小表和大表之间的内部连接期间,索引被忽略

NL连接一定是小表驱动大表效率高吗

在 Spark 中高效地连接一个大表(1TB)和另一个小表(250GB)

hive大表和小表MapJoin关联查询优化

在MySQL查询中,为什么要用小表驱动大表