2014-03-24 30 views
3

我想討論一下這個簡單的postgres查詢,並弄清楚我是否有一些postgres和DBs背後的理論。這裏說到:是否必須使用外鍵來建立連接查詢比例?

-- Query 1 
SELECT posts.*, users.* 
     FROM posts INNER JOIN users 
      ON posts.user_id = users.id 
     WHERE 
      posts.user_id = :id 
     ORDER BY posts.creation_time 

這顯然涉及到兩個表(usersposts)接合在一起。有一個索引(posts.creation_timeposts.user_id)加快搜索。

我的理解是,我還需要一個外鍵關聯posts.user_idusers.id不僅要執行的借鑑誠信爲這樣的一種形式,但奧斯陸,而且可能更重要的是,要加快ON posts.user_id = users.id位查詢。

我說得對嗎?

現在求索這個版本的查詢:

-- Query 2 
SELECT posts.*, users.* 
     FROM posts INNER JOIN users 
      ON posts.user_id = users.id 
     WHERE 
      users.id = :id 
     ORDER BY posts.creation_time 

假設上述的外鍵(posts.creation_timeposts.user_id)存在,將這項查詢的規模,考慮到方程中的變量對對方的生活的加入?

我的猜測是,它不能擴展

感謝

+0

檢查執行計劃,你會知道(但總的來說:索引加速查詢,外鍵不會影響性能 - 隻影響數據的正確性) –

+0

FK用於維護參照完整性。 FK也會對性能產生影響。只要考慮額外的刪除檢查,例如必須進行的檢查,以保持參照完整性。 – ivicaa

+0

好的,但一般情況下,拋開參考文獻的完整性:你是否需要索引參與連接的字段以加快匹配?如果是這樣,它是否應該與查詢中涉及的其他字段(posts.user_id,posts.creation_time)一起作爲多列索引的一部分,還是應該是獨立索引? – nourdine

回答

0

如果某個查詢需要FK上的索引,則取決於查詢執行計劃。如果您從孩子開始,則使用PK索引來查找相應的父行。如果從父級開始,則需要一個高效查找相應的子行。但請記住,有一些隱含的查詢可能發生,例如從父表中刪除一行必須確保沒有相應的子行。 因此,在大多數情況下,將索引放在FK上是一個好主意。

我不確定postgresql,但是在oracle中沒有在FK上創建索引時,甚至可能導致在刪除父行時發生表鎖。

此外,您還可以指出,對於通過「and」(明確或隱含的連接)組合的條件,通常在給定查詢中,每個表只能使用一個索引。在您的例子中,我會放在桌子postsuser_id, creation_time列(順序)組合索引,是適合於

WHERE posts.user_id = :id 

ORDER BY posts.creation_time 
同時

+0

來驗證「*通常每個表只能使用一個索引*」 - Postgres可以在單個語句中愉快地使用每個表的多個查詢。 –

+0

您可以在一個表上使用多個索引,但在給定查詢中只能使用一個索引(除非表在查詢中多次出現) – Drunix

+0

否Postgres *可以在單個查詢中使用多個索引一張桌子。 http://sqlfiddle.com/#!15/55cc4/1這是更好的計劃:http://explain.depesz.com/s/ZurA –

相關問題