簡體   English   中英

100%的MySQL Query Pegs Server-有時

[英]MySQL Query Pegs Server at 100% - Sometimes

我有一個MySQL查詢,它運行得非常非常慢,並且一執行就會將服務器使用率固定在100%。

這是查詢:

SELECT DISTINCT r1.recordID, 
       (SELECT MAX(r2.date) 
            FROM reminders as r2 
            WHERE r2.owner = '$owner' 
                AND r2.recordID = r1.recordID 
                AND r2.status = 'Active' 
                AND r2.followUp != 'true' 
            ORDER BY r2.date DESC LIMIT 1) as maxDate 
    FROM reminders as r1 
    WHERE r1.owner = '$owner' 
        AND (SELECT MAX(r2.date) 
                 FROM reminders as r2 
                 WHERE r2.recordID = r1.recordID 
                     AND r2.status = 'Active' 
                     AND r2.followUp != 'true' 
                 ORDER BY r2.date DESC LIMIT 1) <= '$date' 
        AND (SELECT do_not_call 
                 FROM marketingDatabase 
                 WHERE id = r1.recordID) != 'true' 
        AND r1.status = 'Active' 
    ORDER BY maxDate DESC

我不確定這是寫得不好的查詢(可能是...我是新來的)還是其他東西。 有時,它可以正常工作,並且幾乎立即返回結果,但其他時候則需要很長時間(超過15分鍾)和100%的服務器資源才能返回結果。

知道為什么會這樣嗎? 我可以對查詢采取任何措施來防止這種情況嗎?

提前致謝!

[編輯]

這是說明。

Array
(
    [0] => Array
        (
            [id] => 1
            [select_type] => PRIMARY
            [table] => r1
            [type] => ALL
            [possible_keys] => 
            [key] => 
            [key_len] => 
            [ref] => 
            [rows] => 2073
            [Extra] => Using where; Using temporary; Using filesort
        )

    [1] => Array
        (
            [id] => 4
            [select_type] => DEPENDENT SUBQUERY
            [table] => marketingDatabase
            [type] => eq_ref
            [possible_keys] => PRIMARY
            [key] => PRIMARY
            [key_len] => 4
            [ref] => teleforce.r1.recordID
            [rows] => 1
            [Extra] => 
        )

    [2] => Array
        (
            [id] => 3
            [select_type] => DEPENDENT SUBQUERY
            [table] => r2
            [type] => ALL
            [possible_keys] => 
            [key] => 
            [key_len] => 
            [ref] => 
            [rows] => 2073
            [Extra] => Using where
        )

    [3] => Array
        (
            [id] => 2
            [select_type] => DEPENDENT SUBQUERY
            [table] => r2
            [type] => ALL
            [possible_keys] => 
            [key] => 
            [key_len] => 
            [ref] => 
            [rows] => 2073
            [Extra] => Using where
        )
)

有幾件事會使此查詢變慢。

一個:通常,首先要檢查的是索引。 您必須為r1中的每個記錄執行三個嵌入式查詢。 如果其中任何一個不能有效地使用索引並且必須處理大量記錄,則此查詢將非常緩慢。 查看您的索引,並使用“解釋”查看正在使用的內容。

二:嵌入式查詢往往比聯接要慢。 查看您是否無法將某些嵌入式查詢轉換為聯接。

第三:在這個特定查詢中,據我所知,您正在將“剩余”重新加入自身,只是為了找到max(date)。 為什么不只使用GROUP BY? 我改進此查詢的第一步是:

select r1.recordID, max(r1.date) as maxdate
from reminders as r1
where r1.owner=$owner and r1.status='Active' and r1.followUp!='true'
and (SELECT do_not_call FROM marketingDatabase WHERE id = r1.recordID) != 'true'
group by r1.recordID
having max(r1.date)<=$date
order by maxdate desc

我沒有您的數據庫對此進行測試,但是我認為它將給出相同的結果。

四:我將另一個嵌入式查詢變成一個聯接。 喜歡:

select r1.recordID, max(r1.date) as maxdate
from reminders as r1
join marketingDatabase as m on m.id=r1.recordID
where r1.owner=$owner and r1.status='Active' and r1.followUp!='true'
and m.do_not_call != 'true'
group by r1.recordID, r1.owner
having max(r1.date)<=$date
order by maxdate desc

(我不確定recordID標識什么。從查詢中可以看出,您可以在具有相同recordid的提醒中包含多個記錄。)

五:如果在提醒(所有者,日期)和marketingDatabase(id)上具有索引,則可能會獲得最佳性能。

六:順便說一句,如果“ do_not_call”和followUp是true / false,則它們應該是布爾值而不是varchars。 您只是在浪費磁盤空間和執行時間,而不是布爾TRUE。 這樣就產生了拼寫錯誤的問題,例如“假”或“真”。 在絕對最壞的情況下,使它們成為char(1),T或F。

有時您需要嵌入式查詢,但是它們應該是不得已的方法。

嘗試使用以下命令在reminders.owner上創建索引

CREATE INDEX someNameYouChoose ON reminders(owner);

暫無
暫無

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

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