【问题标题】:MySQL Slow double joinMySQL 慢速双连接
【发布时间】:2012-02-13 10:49:23
【问题描述】:

我有一个带有from_uidto_uid(均已编入索引)的链接表,我想过滤掉某些ID。所以我这样做:

SELECT l.uid
  FROM Link l 
  JOIN filter_ids t1 ON l.from_uid = t1.id 
  JOIN filter_ids t2 ON l.to_uid   = t2.id

现在由于某种原因,这出乎意料地慢:(而每个单独的连接都非常快。它不能使用索引吗?

EXPLAIN 告诉我:

id  select  table type  possible_keys   key      key_len ref  rows  Extra
1   SIMPLE  t1    index Null            PRIMARY  34      Null 12205 Using index
1   SIMPLE  l     ref   from_uid,to_uid from_uid 96      func 6     Using where
1   SIMPLE  t2    index Null            PRIMARY  34      Null 12205 Using where; Using index; Using join buffer

【问题讨论】:

    标签: mysql performance join indexing


    【解决方案1】:

    EXPLAIN 告诉您 JOIN 实际上是从 t1 表开始的。那就是您需要在Link 上添加一个新索引(或者更好地扩展当前的from_uid 索引):

    (from_uid, to_uid, uid)
    

    或者如果uid是主键,那么:

    (from_uid, to_uid)
    

    UPD 你描述的很奇怪。您可以尝试运行:

    SELECT STRAIGHT_JOIN l.uid
    FROM Link l 
    JOIN filter_ids t1 ON l.from_uid = t1.id 
    JOIN filter_ids t2 ON l.to_uid   = t2.id
    

    【讨论】:

    • 我不是专家,但我可以告诉拥有那张桌子的人。从技术上讲,有没有一种方法可以强制 mysql 在不修改表的情况下正确/更快地做到这一点?
    • @Gerenuk,实际上,您应该使数据库适应您的查询,而不是数据库的查询。如果查询不是那么重要,您应该接受它可能效率低下。
    • 好吧,正如我所说,实际上我不能随意修改链接表。问题是是否可以在一个查询中完成,因为拆分查询非常快。顺便说一句,由于某种原因,您建议的索引会使查询变得更慢... :(
    • 如果我使用 from_uid JOIN、ADD INDEX、to_uid JOIN 进行两步查询,我会在大约 4 秒内获得近 50000 个结果行。我相信上面的表格花了大约40秒,但我不敢再试一次,因为管理员抱怨:)
    • 嗯,谢谢你的建议。虽然它没有工作:( 2分钟后它仍然没有停止,并且解释说没有索引被用于链接
    【解决方案2】:

    不知道是否有帮助,但尝试一下:

    select l.uid
    from Link l
    where l.from_uid in (select id from filter_ids)
    and l.to_uid in (select id from filter_ids)
    

    也许它会更好地处理索引。

    【讨论】:

      猜你喜欢
      • 2012-11-11
      • 1970-01-01
      • 2013-03-25
      • 2012-08-17
      • 2013-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多