簡體   English   中英

如何讓這個SQL查詢更快?

[英]How can I make this sql query faster?

我有一個表user_notifications有1100000條記錄,我必須運行以下查詢,但完成查詢需要3分鍾以上才能改善獲取時間。

SELECT `user_notifications`.`user_id`
FROM `user_notifications`
WHERE `user_notifications`.`notification_template_id` = 175
AND (DATE(sent_at) >= DATE_SUB(CURDATE(), INTERVAL 4 day))
AND `user_notifications`.`user_id` IN (
  1203, 1282, 1499, 2244, 2575, 2697, 2828, 2900, 3085, 3989,
  5264, 5314, 5368, 5452, 5603, 6133, 6498..
)

IN塊中的用戶ID有時高達1k。

為了優化,我已在user_notification表中的user_idnotification_template_id列上編制索引。

在此輸入圖像描述

Big IN()列表本質上很慢。 創建一個帶索引的臨時表,並將IN()列表中的值放入該臨時表中,然后您將獲得索引連接而非巨型IN()列表的強大功能。

你好像在尋找一個小日期范圍。 如何根據SENT_AT列獲得索引? 您知道當前查詢使用的索引嗎?

(1)如果您可能需要使用索引,請不要隱藏函數中的列:

AND (DATE(sent_at) >= DATE_SUB(CURDATE(), INTERVAL 4 day))

- >

AND sent_at >= CURDATE() - INTERVAL 4 day

(2)使用“復合”索引

WHERE `notification_template_id` = 175
  AND sent_at >= ...
  AND `user_id` IN (...)

第一列應該是帶'='的列。 目前還不清楚下一步該放什么,所以我建議添加這兩個索引:

INDEX(notification_template_id, user_id, sent_at)
INDEX(notification_template_id, sent_at)

優化器可能會正確地在它們之間進行選擇。

復合指標是一樣的單獨列的索引。

(3)是的,您可以嘗試將IN列表放在tmp表中,但這樣做的成本可能超過收益。 我不認為IN()的1K值是“太多”。

(4) 我的建築指數食譜

暫無
暫無

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

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