Long Sql 查询优化
Long Sql Query optimization
我有一个 sql 查询,当有很多人登录该站点时,它会关闭我的整个服务器。
我花了一整天的时间试图找出如何通过索引教程修复它,但我仍然不明白我该如何修复这个查询,或者我是否完全可以
这是查询:
SELECT t.id,
t.title,
t.s_secret,
t.content,
t.senton,
t.hidden,
t.reported,
t.root_id,
t.sender_id,
t.s_contact_name,
t.s_contact_email,
t.item_id,
t.status_id,
t.event_id,
l.id AS last_id,
l.title AS last_title,
l.s_secret AS last_s_secret,
l.content AS last_content,
l.senton AS last_sentOn,
l.hidden AS last_hidden,
l.reported AS last_reported,
l.root_id AS last_root_id,
l.sender_id AS last_sender_id,
l.s_contact_name AS last_s_contact_name,
l.s_contact_email AS last_s_contact_email,
l.item_id AS last_item_id,
l.status_id AS last_status_id,
l.event_id AS last_event_id,
last.count AS t_count
FROM oc_t_mmessenger_recipients r
JOIN oc_t_mmessenger_message l
ON l.id = r.message_id
JOIN (SELECT Max(im.id) AS max,
Count(1) AS count
FROM oc_t_mmessenger_message im
GROUP BY root_id) last
ON r.message_id = last.max
JOIN oc_t_mmessenger_message t
ON t.id = l.root_id
JOIN oc_t_mmessenger_message_labels ml
ON ( ml.fk_i_message_id = t.id
AND ml.fk_i_label_id = 1
AND ml.fk_i_user_id = 2569 )
WHERE ( r.recipient_id = 2469
OR l.sender_id = 2469 )
ORDER BY last.max DESC
LIMIT 0, 10
如果我通过 phpmyadmin 为 recipient_id 和 sender_id 这样的表创建索引,它会有帮助吗?
任何提示将不胜感激!
谢谢
编辑:
这是当前表的索引:
好的,你有几个我正在考虑的索引,所以你离得不远了。现在内部 select 正在扼杀性能。
以下索引应该加速内部 select:
create index ix1_message on oc_t_mmessenger_message (root_id, id);
您可能希望将查询拆分为两个而不是 OR 语句。
喜欢:
(SELECT
# everything from your query
WHERE r.recipient_id = 2469)
UNION
(SELECT
# everything from your query, again
WHERE l.sender_id = 2469)
这样您应该能够同时使用 recipient_id 和 sender_id 索引。
但正如其他人所说,最大的问题可能是内部 select。
我有一个 sql 查询,当有很多人登录该站点时,它会关闭我的整个服务器。
我花了一整天的时间试图找出如何通过索引教程修复它,但我仍然不明白我该如何修复这个查询,或者我是否完全可以
这是查询:
SELECT t.id,
t.title,
t.s_secret,
t.content,
t.senton,
t.hidden,
t.reported,
t.root_id,
t.sender_id,
t.s_contact_name,
t.s_contact_email,
t.item_id,
t.status_id,
t.event_id,
l.id AS last_id,
l.title AS last_title,
l.s_secret AS last_s_secret,
l.content AS last_content,
l.senton AS last_sentOn,
l.hidden AS last_hidden,
l.reported AS last_reported,
l.root_id AS last_root_id,
l.sender_id AS last_sender_id,
l.s_contact_name AS last_s_contact_name,
l.s_contact_email AS last_s_contact_email,
l.item_id AS last_item_id,
l.status_id AS last_status_id,
l.event_id AS last_event_id,
last.count AS t_count
FROM oc_t_mmessenger_recipients r
JOIN oc_t_mmessenger_message l
ON l.id = r.message_id
JOIN (SELECT Max(im.id) AS max,
Count(1) AS count
FROM oc_t_mmessenger_message im
GROUP BY root_id) last
ON r.message_id = last.max
JOIN oc_t_mmessenger_message t
ON t.id = l.root_id
JOIN oc_t_mmessenger_message_labels ml
ON ( ml.fk_i_message_id = t.id
AND ml.fk_i_label_id = 1
AND ml.fk_i_user_id = 2569 )
WHERE ( r.recipient_id = 2469
OR l.sender_id = 2469 )
ORDER BY last.max DESC
LIMIT 0, 10
如果我通过 phpmyadmin 为 recipient_id 和 sender_id 这样的表创建索引,它会有帮助吗? 任何提示将不胜感激! 谢谢
编辑:
这是当前表的索引:
好的,你有几个我正在考虑的索引,所以你离得不远了。现在内部 select 正在扼杀性能。
以下索引应该加速内部 select:
create index ix1_message on oc_t_mmessenger_message (root_id, id);
您可能希望将查询拆分为两个而不是 OR 语句。 喜欢:
(SELECT
# everything from your query
WHERE r.recipient_id = 2469)
UNION
(SELECT
# everything from your query, again
WHERE l.sender_id = 2469)
这样您应该能够同时使用 recipient_id 和 sender_id 索引。
但正如其他人所说,最大的问题可能是内部 select。