簡體   English   中英

MySQL 刪除一堆記錄后查詢仍然很慢

[英]MySQL queries still slow after deleting bunch of records

我需要一些幫助來解決一些 mysql 問題。 自上周以來,我的網站一直運行緩慢,在聯系我的主機后,我發現一些查詢花費的時間太長,主要是因為表鎖。 我是一名開發人員,但不是 mysql/數據庫專家。 我的主人建議我刪除和/或將有問題的兩個表更改為 innoDB。 因此,由於這些表有很多垃圾數據,我決定刪除一堆記錄。 我會說這兩個表大約是這個問題開始時大小的 25%。 問題是,它仍然沒有任何區別。 所以我的問題:

  1. 我是否需要清除緩存或優化表才能看到效果? 我的主人仍然建議我將這些表更改為 innoDB,這很好,但我不確定為什么刪除這么多記錄並沒有什么不同。
  2. 我還讀到重新創建表比僅僅優化更好? 如果需要,我可以聘請數據庫管理員來幫助我,但如果這很簡單,我至少想嘗試一些事情。 有人可以指導我完成這個。

還要補充一點,它是在 php 5.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;

謝謝!

以下是減慢復雜查詢的因素:

(1)

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

如果它只能讀取 15 行,那就太好了。 但這是不可能的,因為GROUP BYORDER 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 *

如果有任何您最終不需要的大列, *可能會降低一些性能。 拼出所需的列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM