简体   繁体   English

mysql长时间查询

[英]mysql long time query

I have a query on my PHP script it takes too long time! 我对我的PHP脚本有一个查询,需要花费很长时间! When I run the query, server load time increase and server goes down! 当我运行查询时,服务器加载时间增加,服务器停机!

Note: these fields are index: t1.submits_id,t4.submit_id,t3.userid,t1.user_id,owner_id,invited_id,agreed,t2.users_id,,t1.sent_timestamp 注意:这些字段是索引:t1.submits_id,t4.submit_id,t3.userid,t1.user_id,owner_id,invited_id,agreed,t2.users_id,t1.sent_timestamp

SELECT
t1.submits_id,t1.user_id,is_html,shared_from,type,contents,url,sent_timestamp,show_type,album_cached_info,
t2.users_id,name,t2.active,page_url,
t3.time,
t4.like_time
FROM iv6_submits as t1 LEFT JOIN iv6_likes as t4 ON (t1.submits_id = t4.submit_id AND t4.user_id=1)

,iv6_users as t2 LEFT JOIN iv6_onlineusers as t3 ON (t2.users_id=t3.userid)
WHERE
t1.submits_id<19000 AND 
(t1.user_id=1 OR t1.user_id in
    (select IF(owner_id=1,invited_id,owner_id) as id
        from iv6_add_lists
            where ((owner_id=1 or invited_id=1) AND agreed=1) OR (owner_id=1 AND agreed=2)))
AND t2.users_id=t1.user_id
ORDER BY t1.sent_timestamp DESC LIMIT 10

I'd start by writing the query as: 我首先将查询编写为:

    SELECT t1.submits_id, 
           t1.user_id,
           is_html,  /* I'd append all table aliases here */
           shared_from,
           type,
           contents,
           url,
           sent_timestamp,
           show_type,
           album_cached_info,
           t2.users_id,
           name,
           t2.active,page_url,
           t3.time,
           t4.like_time
      FROM iv6_submits as t1
      JOIN iv6_users as t2
        ON t2.users_id=t1.user_id
 LEFT JOIN iv6_likes as t4 
        ON t4.submit_id = t1.submits_id 
       AND t4.user_id=1
 LEFT JOIN iv6_onlineusers as t3 
        ON t3.userid = t2.users_id
     WHERE t1.submits_id<19000 
       AND (
             t1.user_id=1 
          OR t1.user_id IN (
        SELECT IF(owner_id=1,invited_id, owner_id) as id
          FROM iv6_add_lists
         WHERE ((owner_id=1 OR invited_id=1) AND agreed=1) 
            OR (owner_id=1 AND agreed=2))
           )
  ORDER BY t1.sent_timestamp DESC 
     LIMIT 10

From this and your explain i'd guess that t1.submits_id< 19000 reduces your result set the most. 从这个和您的解释中,我猜想t1.submits_id< 19000会最大程度地减少您的结果集。 So I'd then try: 因此,我尝试:

    ...
      FROM iv6_submits as t1 USE INDEX (submits_id)
    ...

Your subquery is also v. strange, i'd rewrite it as something like: 您的子查询也很奇怪,我将其重写为:

   SELECT invited_id 
     FROM iv6_add_lists 
    WHERE owner_id = 1 
      AND agreed BETWEEN 1 AND 2
UNION ALL 
   SELECT owner_id 
     FROM iv6_add_lists  
    WHERE invited_id = 1
      AND agreed = 1
      AND owner_id != 1

And see if that helps as well, you can hint an index for each FROM. 并查看是否也有帮助,您可以为每个FROM提示一个索引。 A composite index on (owner_id, agreed, invited_id) and (invited_id, agreed, owner_id) should cover both queries respectively. (owner_id,同意,被邀请,id)和(invited_id,同意,所有者_id)的综合索引应分别覆盖这两个查询。

You also could write this as 您也可以这样写

   SELECT 1
    UNION
   SELECT DISTINCT invited_id 
     FROM iv6_add_lists 
    WHERE owner_id = 1 
      AND agreed BETWEEN 1 AND 2
    UNION 
   SELECT DISTINCT owner_id 
     FROM iv6_add_lists  
    WHERE owner_id != 1
      AND agreed = 1
      AND invited_id = 1 

And JOIN it to your t1 instead of the AND (t1.user_id=1 OR ...) 并将其JOIN到您的t1而不是AND (t1.user_id=1 OR ...)

UPDATE 更新

    SELECT t1.submits_id, 
           t1.user_id,
           is_html,  /* I'd append all table aliases here */
           shared_from,
           type,
           contents,
           url,
           sent_timestamp,
           show_type,
           album_cached_info,
           t2.users_id,
           name,
           t2.active,page_url,
           t3.time,
           t4.like_time
      FROM iv6_submits as t1
      JOIN iv6_users as t2
        ON t2.users_id=t1.user_id
      JOIN (
        SELECT 1 user_id
         UNION
        SELECT DISTINCT invited_id 
          FROM iv6_add_lists 
         WHERE owner_id = 1 
           AND agreed BETWEEN 1 AND 2
         UNION 
        SELECT DISTINCT owner_id 
          FROM iv6_add_lists  
         WHERE owner_id != 1
           AND agreed = 1
           AND invited_id = 1
           ) t5
        ON t1.user_id = t5.user_id
 LEFT JOIN iv6_likes as t4 
        ON t4.submit_id = t1.submits_id 
       AND t4.user_id=1
 LEFT JOIN iv6_onlineusers as t3 
        ON t3.userid = t2.users_id
     WHERE t1.submits_id<19000 
  ORDER BY t1.sent_timestamp DESC 
     LIMIT 10

I suggest you split the query to see where the resources are being consumed. 我建议您拆分查询以查看在哪里消耗了资源。

  • Execute the subquery in the WHERE section and see if it runs fast 执行WHERE部分中的子查询,看看它是否运行很快
  • Remove the left joins and then add one by one to see where it all goes down. 删除左连接,然后一个接一个地添加,以查看所有下降。
  • Remove all the "WHERE" conditions and add one by one. 删除所有“ WHERE”条件,然后一一添加。
  • Try to run the query without the "ORDER BY" statement. 尝试运行不带“ ORDER BY”语句的查询。

You did not referred t4.user_id as being indexed, it may be important. 您没有将t4.user_id引用为已索引,这可能很重要。 Table iv6_add_lists also should have all the fields present in WHERE statement indexed. 表iv6_add_lists也应该索引WHERE语句中存在的所有字段。

Also suggest you to make an INNER JOIN between t1 and t2: 还建议您在t1和t2之间建立一个INNER JOIN:

FROM (iv6_submits as t1 
        LEFT JOIN iv6_likes as t4 ON (t1.submits_id = t4.submit_id AND t4.user_id=1))
     INNER JOIN 
    (iv6_users as t2 
        LEFT JOIN iv6_onlineusers as t3 ON (t2.users_id=t3.userid))

    ON t2.users_id=t1.user_id

Then ou can remove 然后你可以删除

AND t2.users_id=t1.user_id

from the WHERE statement. 从WHERE语句中。

Try This. 尝试这个。

SELECT
    t1.submits_id,t1.user_id,is_html,shared_from,type,contents,url,sent_timestamp,show_type,album_cached_info,
    t2.users_id,name,t2.active,page_url,
    t3.time,
    t4.like_time
FROM 
    iv6_submits as t1 
    LEFT JOIN iv6_users as t2 ON t2.users_id = t1.user_id
    LEFT JOIN iv6_likes as t4 ON t1.submits_id = t4.submit_id AND t4.user_id = 1
    LEFT JOIN iv6_onlineusers as t3 ON t2.users_id = t3.userid
WHERE
    t1.submits_id < 19000 
AND 
    (t1.user_id = 1 OR t1.user_id in 
        (
            select IF(owner_id=1,invited_id,owner_id) as id from iv6_add_lists where (invited_id=1 AND agreed=1) OR ( owner_id=1 AND agreed IN (1,2) ) 
        )
    )
ORDER BY t1.sent_timestamp DESC LIMIT 1

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

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