2012-09-04 194 views
0

我在PHP中遇到这个查询的问题。速度太慢,执行后几分钟无法连接到服务器。我一直在从主查询中移除单独的子查询,并发现它在完成最后一个内部查询后非常顺利。缓慢的子查询mysql查询

表“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

不使用IN,它的缓慢。因为IN不使用JOIN语法对结果进行索引。 – jtheman

+0

这只是一个猜测,但看起来像嵌套子查询,所以这势必会让事情变得更慢。这意味着每行都运行“$ y”的子查询,然后针对“$ y”的子查询的每个结果运行子子查询。也许你应该在查询上运行解释,看看发生了什么 – Gohn67

+0

我不清楚你的查询想要做什么。但也许你不需要所有这些子查询,并可以使用连接? – Gohn67

回答

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 
0

测试,这会产生相同的结果 - 要快很多。

  1. 更换陈述与内部连接。查询优化器更多的机会来优化这种方式
  2. 消除你或声明 - 我这样做是使用UNION。我认为如果你愿意的话,你可以用LEFT JOIN来消除OR。
  3. 你需要测试一下 - 我没有任何样本数据。
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