簡體   English   中英

Mysql 查詢性能多重和或條件

[英]Mysql query performance multiple and or conditions

我在 mysql 中有這個查詢,性能很差。

select `notifiables`.`notification_id` 
from `notifiables` 
where `notifiables`.`notification_type` in (2, 3, 4) 
  and (    (    `notifiables`.`notifiable_type` = 16 
            and `notifiables`.`notifiable_id` = 53642) 
        or (    `notifiables`.`notifiable_type` = 17 
            and `notifiables`.`notifiable_id` = 26358) 
        or (    `notifiables`.`notifiable_type` = 18 
            and `notifiables`.`notifiable_id` = 2654)) 
order by `notifiables`.`id` desc limit 20

是否可以以任何方式優化此查詢。 請幫忙 這個表有 2M 行。 搜索時間長達 1-4 秒

附表索引

您可以從您想要的數據中制作不同類型的“視圖”,然后加入它們。

使用下一個語法:

SELECT notification_id
FROM notifiables 
WHERE notification_type IN (2, 3, 4) 
  AND (notifiable_type, notifiable_id) IN ( (16, 53642), (17, 26358), (18, 2654) )
ORDER BY id DESC LIMIT 20

通過(notification_type, notifiable_type, notifiable_id)(notifiable_type, notifiable_id, notification_type)創建索引(取決於單獨的條件選擇性)。

或創建覆蓋索引( (notification_type, notifiable_type, notifiable_id, notification_id)(notifiable_type, notifiable_id, notification_type, notification_id) )。

可能的解決方案:

  • OR轉換為UNION (請參閱 @hongnhat)

  • 行構造函數(見@Akina)

  • 添加

     AND notifiable_type IN (16, 17, 18)
  • 索引提示。 我不喜歡這個,因為它往往弊大於利。 但是,優化器錯誤地選擇了PRIMARY KEY(id) (因為ORDER BY而不是一些過濾器,根據基數應該非常好。

  • INDEX(notification_type, notifiable_type, notifiable_id, id, notification_id) -- 這是“覆蓋”,這會有所幫助,因為索引可能比數據集“小”。 添加此索引時,請DROP您當前的INDEX(notification_type) ,因為它會分散優化器的注意力。

  • VIEW不太可能有幫助。

暫無
暫無

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

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