使用子查询缓慢查询mysql

时间:2012-09-04 00:36:14

标签: php mysql performance

我在PHP中遇到此查询的问题。它太慢了我执行它后几分钟就无法连接到服务器。我一直在从主查询中删除单独的子查询,并发现,在我删除最后一个内部查询后它完全顺利。

表“u”有30.000行,表“u_r”在17.000左右,表“u_s”在13.000左右,表“s”在100左右。尽管表“u_r”和“u_s”有很多行,但只有2- 3行具有与条件匹配的相同“id_u”。

我希望,我提供了足够的信息。如果您还需要了解其他信息,请随时在评论中提问。

SELECT DISTINCT id_p
FROM u
WHERE
    '$x' IN(
        SELECT id_p
        FROM u_p
        WHERE id_u=u.id_u
    )
    AND
    (
        '$y' IN (
            SELECT id_r
            FROM u_r
            WHERE id_u=u.id_u
        )
        OR
        '$y' IN (
            SELECT DISTINCT id_r
            FROM s
            WHERE id_s IN (
                SELECT id_s //without this query, everything works fine
                FROM u_s
                WHERE id_u=u.id_u
            )
        )
    )

2 个答案:

答案 0 :(得分:1)

我认为你可以改变:

SELECT DISTINCT id_r 
        FROM s 
        WHERE id_s IN ( 
            SELECT id_s //without this query, everything works fine 
                FROM u_s 
                WHERE id_u=u.id_u 

SELECT s.id_s
        FROM u_s 
             INNER JOIN s ON u_s=id_u=u.id_u
        WHERE u_s.id_u = u.id_u
        GROUP BY s.id_r

未经测试,因为我试图将头部包裹在结构周围。

还要记得检查索引。作为一个粗略的指南,您应该在“WHERE”中有任何内容,并且“ON”中的任何内容都有索引:

u_p.id_u
u_r.id_u
u_s.id_u
s.id_s

答案 1 :(得分:0)

测试这会产生相同的结果 - 应该快得多。

  1. 用内部联接替换IN语句。查询优化器有更多机会优化这种方式
  2. 消除你的OR声明 - 我是用UNION做的。如果你愿意的话,我想你可以使用LEFT JOIN消除OR。
  3. 您需要对此进行测试 - 我没有任何样本数据。
  4. select distinct id_p
    from u
    inner join u_p
    on u.id_u = u_p.id_u
    and u_p.id_u = '$x'
    inner join
    (
      select id_r.id_u
      from u_r
      where id_r = '$y'   
      union
      select id_r
      from s
      inner join u_s
      on s.id_u = u_s.id_u
      where id_r = '$y'
    ) as subq
    on u.id_u = subq.id_u