2015-05-28 55 views
0

接合相同的表,如果我有兩個表條目entry_metadata,與entry_metadata作爲通過entry_id和變量引用的條目的說明表。PostgreSQL的:替代多次

,如果我有這樣的:

進入

id | name | 
------------- 
1 | entry1 | 
2 | entry2 | 
3 | entry3 | 

entry_metadata

id | entry_id | variable | value 
1 | 1  | width | 10 
2 | 1  | height | 5 
3 | 2  | width | 8 
4 | 2  | height | 7 
5 | ... | .... | .. 

和我越來越表:

id | name | width | height| ... | ... 
----------------------------------------- 
1 | entry1 | 10 | 5 | 
2 | entry2 | 8 | 7 | 
3 | entry3 | .. | .. | 

由SQL:

select e.name, em.width, emr.height 
from 
    public.entry e 
left join 
    public.entry_metadata em 
on 
    em.entry_id = e.id and em.variable = 'width' 
left join 
    public.entry_metadata emr 
on 
    emr.entry_id = e.id and emr.variable = 'height' 

上述作品查詢。但是,當我添加更多變量來從條目元數據中獲取值(entry_metadata表包含各種各樣的變量)時。查詢變得非常慢。我所做的每個連接都會大大減慢執行速度。有沒有辦法解決這個問題?

回答

2

您也可以使用條件聚集做到這一點:

select id, name, 
     max(case when variable = 'width' then value end) as width, 
     max(case when variable = 'height' then value end) as height 
from public.entry_metadata em 
group by id, name; 

添加額外的列只是增加更多的聚合功能。

+0

這會比連接替代方案更快嗎? – muffin

+0

@muffin。 。 。您需要在數據和系統上嘗試它。有很多專欄,它可能會更快,但沒有保證。 –

1

只需使用子查詢爲此:

SELECT 
    e.id, 
    e.name, 
    (SELECT em.value FROM public.entry_metadata em WHERE em.entry_id = e.id AND em.variable = 'width') AS width, 
    (SELECT em.value FROM public.entry_metadata em WHERE em.entry_id = e.id AND em.variable = 'height') AS height 
FROM 
    public.entry e 

所以對於每一個新的變量,你只需要添加更多的子查詢中。

+0

我測試過了,但是比加入速度慢很多 – muffin

+0

你有索引你的表嗎?可能缺少entry_metadata.entry_id的索引? – sfrutig

+1

是的..它實際上是好的,如果它是2連接..但如果我得到3至4 ..表現收費是指數.. – muffin

0

有沒有辦法解決這個問題?條目的元數據的值存儲 -

有,帶addtional柱在entry與鍵替換entry_metadata表(可能的解決方案是hstorejsonb)。

Btw。你的表格代表衆所周知的有爭議的數據庫設計模式,稱爲「實體屬性值」。