[英]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.