[英]Slow query with left outer join and is null condition
我有一個簡單的查詢(postgresql,如果這很重要),它檢索some_user的所有項目,不包括她在心願單上的項目 :
select i.*
from core_item i
left outer join core_item_in_basket b on (i.id=b.item_id and b.user_id=__some_user__)
where b.on_wishlist is null;
以上查詢運行在~50000ms(是的,數字是正確的)。 如果我刪除“b.on_wishlist為null”條件或使其“b.on_wishlist is not null”,則查詢將在大約50ms內運行(相當大的變化)。
該查詢具有更多的連接和條件,但這是無關緊要的,因為只有這一個減慢了它。
有關數據庫大小的一些信息:
我在這兩個表上沒有任何索引(除了id和外鍵)。
問題是: 我該怎么做才能讓這個更快? 我自己今晚有一些想法可以查看,但如果可能的話,我希望你們能幫忙。
謝謝!
嘗試使用不存在:
select i.*
from core_item i
where not exists (select * from core_item_in_basket b where i.id=b.item_id and b.user_id=__some_user__)
很抱歉添加第二個答案,但stackoverflow不允許我正確格式化評論,因為格式化是必不可少的,我必須發布答案。
幾種選擇:
讓我們知道結果 :)
您可能想要更多地解釋此查詢的目的 - 正如某些技術所做的那樣,有些技術沒有意義,具體取決於用例。
你多久運行一次?
它是僅為1個用戶運行,還是在某種循環中為所有用戶運行?
做:解釋分析並將輸出放在explain.depesz.com上,這樣你就會明白它為什么這么慢。
您是否嘗試在on_wishlist
上添加索引 ?
似乎需要為查詢中的每一行檢查此列。 如果您的表很大,這可能會對查詢速度產生很大影響。
當您將on_wishlist
條件放在where
子句中時,這將導致它(取決於查詢計划器決定的內容)在執行連接后進行評估,因此必須對連接產生的每一行進行比較。 core_items
和core_item_in_basket
表都非常大,並且您沒有該列的索引,因此查詢優化器幾乎沒有,這可能會導致查詢時間過長。
core_user
的大小應該沒有影響(因為它沒有在查詢中引用)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.