【问题标题】:Long Sql Query optimizationLong Sql 查询优化
【发布时间】:2018-04-20 20:33:14
【问题描述】:

当有很多人登录到该站点时,我有一个 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 这样的表创建索引,它会有所帮助吗? 任何提示将不胜感激! 谢谢。

编辑:

这是当前表的索引:

【问题讨论】:

  • EXPLAIN 对您的查询有何看法?
  • 让我看看...
  • 第一个内部选择读取整个表 oc_t_mmessenger_message。您能发布您目前拥有哪些索引吗?
  • 谢谢,我编辑了帖子并在底部添加了表 oc_t_messenger_message 和 oc_t_messenger_recipients 的索引图像
  • 表格有多少行?

标签: php mysql sql osclass


【解决方案1】:

您可能希望将查询拆分为两个而不是 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 索引。

但正如其他人所说,最大的问题可能是内部选择。

【讨论】:

    【解决方案2】:

    好的,你有几个我正在考虑的索引,所以你离得不远。现在,内部选择正在扼杀性能。

    以下索引应该加快内部选择:

    create index ix1_message on oc_t_mmessenger_message (root_id, id);
    

    【讨论】:

    • 谢谢,我添加了这个索引,但是(这可能是一个转储问题)不是已经有 root_id 和 id 索引了吗?我还读到here 说“您选择的排序规则会显着影响数据库中查询的性能”我正在使用 utf8_general_ci 我可以将其更改为更快的东西而不会丢失任何东西吗?
    • 一个组合索引 (root_id, id) 不同于两个单独的索引 (root_id) 和 (id)。结合起来解决不同的问题。
    • 谢谢,我希望它至少能部分解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 2014-02-04
    • 2014-11-16
    • 2011-06-22
    • 2015-08-10
    相关资源
    最近更新 更多