代码之家  ›  专栏  ›  技术社区  ›  Erick

关于查询优化的见解

  •  0
  • Erick  · 技术社区  · 15 年前

    我试图在这里基本上找到有运动和娱乐的用户;活动所针对的区域。在acces[users]表中,大约有1700个用户。每个人都可以有一定数量的体育兴趣和一个地区。

    SELECT a.user, pp.courriel
    FROM acces a
    LEFT JOIN acces_profil_sport ap ON ap.id = a.id
    LEFT JOIN profil_perso pp ON pp.id = a.id
    WHERE ap.sport_id IN
      (
        SELECT ac.sport_id
        FROM activite_sport ac
        RIGHT JOIN activite a ON a.activite_id = ac.activite_id AND a.is_cron = 1 AND a.cron_processed = 0
       )
      AND pp.region_id IN
      (
        SELECT ar.region_id
        FROM activite_region ar
        RIGHT JOIN activite a ON a.activite_id = ar.activite_id AND a.is_cron = 1 AND a.cron_processed = 0
      )
    GROUP BY a.id
    

    如果删除sport查找,查询运行大约需要30秒。否则,它会花费很长时间,并使用mysql使用大约99%的进程。

    有什么帮助的提示吗?

    [编辑:表格结构]
    _ id(profil的钥匙/外键 _ id])[其他一些字段]
    profil _ 个人:个人 _ id(主键)Courrel,区域 id,id(访问的外键[id])[一些其他字段]
    _ profil _ 运动:身份证/运动 _ id(双主键),niveau _ _ id)

    3 回复  |  直到 15 年前
        1
  •  4
  •   Jeff Ferland    15 年前

    解释选择。。。

    在我看来,这些应该都是正常的连接,因为两个左连接只有在它们存在时才会起作用。如果它们为null,则由于所需的subselect匹配,您将不会得到一行。

    至于右边的连接,你需要ar位,它不是右边的一部分。我要么把它们取下来,要么把它们做成直线连接。我假设,既然您正在检查看起来像未处理的cron工作,那么您希望保留它们。

    SELECT a.user, pp.courriel
    FROM acces 
    JOIN acces_profil_sport ap ON ap.id = a.id
    JOIN profil_perso pp ON pp.id = a.id
    JOIN activite_sport ac ON ac.sport_id = ap.sport_id
    JOIN activite a1 ON a.activite_id = ac.activite_id AND a.is_cron = 1 AND a.cron_processed = 0
    JOIN activite_region ar ON ar.region_id = pp.region_id
    JOIN activite a2 ON a.activite_id = ar.activite_id AND a.is_cron = 1 AND a.cron_processed = 0
    
        2
  •  0
  •   James Socol    15 年前

    你们有电视吗 is_cron cron_processed ? 这有助于加快速度。

        3
  •  0
  •   araqnid    15 年前
    SELECT acces.user, courriel
    FROM acces
    JOIN profil_perso ON acces.id = profil_perso.id
    WHERE EXISTS (SELECT 1 FROM acces_profil_sport JOIN activite_sport on acces_profil_sport.sport_id = activite_sport.sport_id JOIN activite ON activite.activite_id = activite_sport.activite_id WHERE is_cron = 1 AND cron_processed = 0 AND acces_profil_sport.id = profil_perso.id)
    AND EXISTS (SELECT 1 FROM activite_region JOIN activite ON activite_region.activite_id = activite.activite_id WHERE is_cron = 1 AND cron_processed = 0 AND activite_region.region_id = profil_perso.region_id);