简体   繁体   English

带有子查询的慢速MySQL查询

[英]Slow mysql query with subqueries

I'm experiencing a problem with this query in PHP. 我在PHP中遇到此查询问题。 It is so slow I cannot connect to the server for few minutes after executing it. 太慢了,执行完几分钟后我无法连接到服务器。 I've been removing separate subqueries away from main query and found out, that it works perfectly smooth, after I remove the last inner query. 我一直在从主查询中删除单独的子查询,发现在删除最后一个内部查询后,它的工作非常顺畅。

Table "u" has 30.000 rows, table "u_r" around 17.000, table "u_s" around 13.000 and table "s" around 100. Even though tables "u_r" and "u_s" have lots of rows, only 2-3 rows have same "id_u" that matches the condition. 表“ u”具有30.000行,表“ u_r”约为17.000,表“ u_s”约为13.000,表“ s”约为100。即使表“ u_r”和“ u_s”具有很多行,但只有2-3行符合条件的相同“ id_u”。

I hope, I provided enough information. 希望我提供了足够的信息。 If you need to know anything else, feel free to ask in the comments. 如果您需要了解其他任何信息,请随时在评论中提问。

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
            )
        )
    )

I think you can change: 我认为您可以更改:

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 

to

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

Not tested as I'm trying to wrap my head around the structure. 未经测试,因为我试图将头缠绕在结构上。

Also remember to check the indexes. 还记得检查索引。 As a rough guide, you should have anything in the "WHERE" and anything in the "ON" indexed: 作为粗略的指导,您应该在“ WHERE”中包含任何内容,并在“ ON”中包含任何索引内容:

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

Test that this produces the same results - should be much faster. 测试是否会产生相同的结果-应该更快。

  1. Replace the IN statements with inner joins. 用内部联接替换IN语句。 More opportunities for query optimiser to optimise this way 查询优化程序有更多机会以这种方式进行优化
  2. Eliminate your OR statement - I did this using a UNION. 消除您的OR语句-我使用UNION做到了。 I think you could probably eliminate the OR using a LEFT JOIN instead if you wanted. 我认为,您可以根据需要使用LEFT JOIN消除OR。
  3. You'll need to test this - I don't have any sample data. 您需要进行测试-我没有任何示例数据。
 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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM