mysql查询在删除一堆记录后仍然很慢

htrmnn0y  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(394)

我需要一些帮助来解决一些mysql问题。我的网站从上周开始运行缓慢,在联系我的主机后,我发现一些查询花费的时间太长,主要是因为表锁。我是一个开发人员,但没有mysql/数据库Maven。我的主人建议我要么删除这两个表,要么把它们改成innodb。因此,由于这些表有很多垃圾数据,我决定删除一堆记录。我想说,这两个表的大小大约是这个问题开始时的25%。问题是,它仍然没有产生任何影响。所以我的问题是:
我需要清除缓存还是优化表才能看到效果?我的主人仍然建议我把这些表改成innodb,这很好,但我不知道为什么删除这么多记录没有什么不同。
我还读到,它是更好地重建表比只是优化?如果需要,我可以聘请一个数据库管理员来帮助我,但我想至少尝试一些事情,如果这是简单的。有人能帮我解决这个问题吗。
还有一件更重要的事情需要补充,那就是运行在php5.4和mysql 5.6上的遗留网站
下面是锁定表的示例查询之一。

SELECT `m`.`message_id`, COUNT(`m`.`message_id`) AS `mails_count`, `m`.`sender_id`, `m`.`recipient_id`, 
            `m`.`text`, `m`.`is_readable`, `m`.`time_stamp` AS `last_message_ts`, `c`.`conversation_id`, `c`.*, `ms`.`is_replied`
            FROM `mailbox_conversation` AS `c` 
            INNER JOIN (
                SELECT * FROM `mailbox_message` 
                WHERE `recipient_id`=67404  AND IF (`sender_id`!=67404, `status`='a', 1) ORDER BY `time_stamp` DESC  
            ) AS `m` ON(`m`.`conversation_id`=`c`.`conversation_id`) 
            INNER JOIN (
                SELECT `conversation_id`, IF(`sender_id`=67404,'yes','no') AS `is_replied` FROM `mailbox_message` 
                WHERE (`recipient_id`=67404 OR `sender_id`=67404) ORDER BY `time_stamp` DESC 
            ) AS `ms` ON(`ms`.`conversation_id`=`c`.`conversation_id`)
            WHERE (`c`.`initiator_id`=67404 OR `interlocutor_id`=67404)
            AND `c`.`bm_deleted` NOT IN (IF(`c`.`initiator_id`=67404, '1, 3','2, 3'))           
             AND IF (`sender_id`!=67404, `status`='a', 1)
            GROUP BY `c`.`conversation_id`
            ORDER BY `m`.`time_stamp` DESC  LIMIT 0,15;

谢谢您!

ctzwtxfj

ctzwtxfj1#

以下是减慢复杂查询速度的因素:
(1)

GROUP BY  `c`.`conversation_id`
    ORDER BY  `m`.`time_stamp` DESC
    LIMIT  0,15;

如果它只能读15行就好了。但这是不可能的,因为 GROUP BY 以及 ORDER BY 不匹配。此外,它们涉及多个表,因此不需要使用索引(一 INDEX 只能引用一个表。)
(2)

AND  IF (`sender_id`!=67404, `status`='a', 1)

(`recipient_id`=67404  OR  `sender_id`=67404)

(`c`.`initiator_id`=67404  OR  `interlocutor_id`=67404)

这两个都太复杂,无法使用任何索引。 OR 是一个性能杀手;它有时可以变成一个 UNION . (但你需要 UNIONs 来处理这里的一切。)如果可以写的话 sender_id = 67404 or status='a' --不会更快,但(对我)会更清楚。
一个案例:

( SELECT ... from mailbox_message WHERE `recipient_id`=67404 )
UNION ALL
( SELECT ... from mailbox_message WHERE `sender_id`=67404 )

需要这个吗 UNION : INDEX(recipient_id) 以及 INDEX(sender_id) .
(3)

JOIN ( SELECT ... )

这通常是不可优化的,尤其是当存在多个这样的问题时。
(4)

JOIN ( SELECT ... ORDER BY ... )

这个 ORDER BY 将被忽略。囊性纤维变性 ONLY_FULL_GROUP_BY .
(5)

SELECT *

如果有任何你最终不需要的大柱子, * 可能需要一些性能。写出所需的列。

相关问题