[英]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. 我建议您拆分查询以查看在哪里消耗了资源。
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.