2011-11-23 76 views
0

動態順序我有一個SQL查詢我在PostgreSQL的運行沿着這行的樣子:(ActiveRecord的生成所以道歉,如果它不是優化的,因爲它可以)索引通過聲明

SELECT DISTINCT items.id, 
    CASE WHEN items.marker is not null 
      THEN (items.rating - (educations.cards_done - items.marker)) 
     WHEN items.marker is null 
      THEN 0 
    END AS order 
FROM items 
INNER JOIN educations ON educations.item_id = items.id 
WHERE items.active = true 
ORDER BY 
    CASE WHEN items.marker is not null 
      THEN (items.rating - (educations.cards_done - items.marker)) 
     WHEN items.marker is null 
      THEN 0 
    END 
LIMIT 10 

PostgreSQL中的case語句可以在該訂單上有索引嗎?如果沒有,有沒有其他方法可以加快這個查詢? 感謝您提供任何幫助!

回答

1

您可以從優化CASE語句本身開始。第二個WHEN是多餘的。只能有兩種情況(NULLNOT NULL)。簡化:

CASE WHEN items.marker is not null 
    THEN ((items.rating + items.marker) - educations.cards_done) 
ELSE 0 END 

至於索引而言,我不知道的方式在索引中使用來自多個表的值。您必須在其中一個表中使用materialized view或冗餘列,這可以通過觸發器進行更新。我只會想到這樣的事情,如果ORDER的表現非常重要,並且涉及的表大部分被讀取並且很少被寫入。

我假設您已經有educations.item_iditems.id上的索引? (主鍵是一個自動索引,外鍵是

根據項目與active = true百分比上items部分索引,可能的幫助。積極的項目將不得不成爲少數人的工作。

CREATE INDEX foo_idx ON items(id) WHERE active; 

如果在您的查詢中使用索引,則使用EXPLAIN ANALYZE進行測試。如果您選擇涉及的表的大部分,順序掃描將會更快,索引也不會被使用。