2009-07-01 79 views
0

我有一個簡單的查詢(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不爲空」,查詢運行大約50ms(相當多的變化)。

該查詢有更多的連接和條件,但這是無關緊要的,因爲只有這個會降低速度。

數據庫的大小一些信息:

  • core_items有〜10.000記錄
  • core_user了〜5.000記錄
  • core_item_in_basket了〜2.000
  • 記錄(其中約50%有 on_wishlist = true,其餘爲空)

我沒有任何索引(id除外和外鍵)在這兩個表上。

現在的問題是:我應該怎麼做才能讓這個運行速度更快?今天晚上我有幾個想法可以看看,但是如果可能的話,我希望你們幫忙。

謝謝!

+0

也許你可以看看執行計劃,看看是什麼問題。理論上,如果餘額爲50/50,則請求'爲空'或'非空'必須具有相同的執行計劃。表的空stastistics必須是錯誤的! – 2009-07-01 15:18:19

+0

@ Scorpi0不完全。請記住,這是一個外連接。 core_item_in_basket的空統計確實是50/50,但查詢試圖將來自core_item的每條記錄與來自core_item_in_basket的記錄進行匹配,從而在連接的右側產生大量額外的空值。 – michuk 2009-07-01 15:54:35

+0

兩種行匹配條件「where b.on_wishlist爲null」1. core_item中的行沒有匹配的core_item_in_basket; 2. core_item中的行與core_item_in_basket中的匹配,但其中一些匹配的匹配on_wishlist爲空 您是否希望這兩組行? – 2009-07-04 18:31:30

回答

2

對不起,添加第二個答案,但stackoverflow不讓我格式正確的意見,因爲格式是必不可少的,我必須發佈答案。

幾個選項:

  1. CREATE指標Q10 ON core_item_in_basket(USER_ID,ITEM_ID)WHERE on_wishlist爲空;
  2. 相同的索引,但改變列中的順序。
  3. SELECT i。* FROM core_item i WHERE i.id not in(select item_id FROM core_item_in_basket WHERE on_wishlist爲null且user_id = __some_user__); (這個查詢可以受益於來自#1索引的索引,但不會從索引#2獲益
  4. SELECT * from core_item where id in(select id from core_item EXCEPT select item_id FROM core_item_in_basket WHERE on_wishlist is null AND user_id = __some_user__) ;

讓我們知道結果:)

5

嘗試使用不存在:

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__) 
+0

但是這忽略了「b.on_wishlist爲空」的情況,這似乎是這裏放緩的因素。 – 2009-07-01 15:32:04

1

你試過添加指數on_wishlist

看來這個列需要檢查查詢中的每一行。如果你的表格很大,這可能會對查詢速度產生相當大的影響。

當你在where子句中放入on_wishlist條件時,會導致它(取決於查詢平面器決定的內容)在連接執行後進行評估,因此必須對可能產生的每一行進行比較從加入。 core_itemscore_item_in_basket這兩個表都非常大,而且您沒有該列的索引,因此查詢優化器可以做的事情很少,這可能會導致查詢時間過長。

core_user的大小應該沒有影響(因爲它沒有在查詢中引用)。

2

您可能想要解釋更多關於此查詢的用途 - 根據使用情況,某些技術可能會有所改變,有些可能無意義。

你多久運行一次?

它只運行一個用戶,還是在某種循環中爲所有用戶運行?

做:解釋分析並把輸出放在explain.depesz.com上,這樣你就會明白爲什麼它太慢了。