2012-12-03 43 views
0

我有一個SQL Server數據庫,我需要存儲一個未知的列數,所以我有2個表是這樣的:爲了優化查詢組成的子查詢

  1. Master,這些列:id, data1, data2(固定列)
  2. unknown_fields這些列:id_master_record, id_field, value_field

我不喜歡這樣的查詢:

SELECT id, data1, data2, 
    (SELECT value_field FROM unknown_fields 
    WHERE id_master_record = Master.id AND id_field = 1) AS data3 
    (SELECT value_field FROM unknown_fields 
    WHERE id_master_record = Master.id AND id_field = 2) AS data4 
    (SELECT value_field FROM unknown_fields 
    WHERE id_master_record = Master.id AND id_field = 3) AS data5 
... SO for each 
FROM Master 

我想知道是否有更好的方法來執行此查詢。

+0

你的意思是'AND id_field =',而不是'AND id_master_record ='在行尾? – Blorgbeard

+0

是的,對不起,我錯了 –

回答

4

你可以試試這個,它可能會稍微快一點。最好測試兩者。對(id_master_record, id_field)上的第二個表進行聚類可能會有助於這兩個查詢。

Select 
    m.id, 
    m.data1, 
    m.data2, 
    Max(Case u.id_field When 1 Then u.value_field End) As data3, 
    Max(Case u.id_field When 2 Then u.value_field End) As data4, 
    Max(Case u.id_field When 3 Then u.value_field End) As data5 
From 
    xmaster m 
    Left Outer Join 
    unknown_fields u 
    On m.id = u.id_master_record 
Group By 
    m.id, 
    m.data1, 
    m.data2; 

您也可以嘗試使用Pivot

Select 
    id, 
    data1, 
    data2, 
    [1] as data3, 
    [2] as data4, 
    [3] as data5 
From (
    Select 
    m.id, 
    m.data1, 
    m.data2, 
    id_field, 
    value_field 
    From 
    Master m 
     left outer join 
    unknown_fields u 
     On m.id = u.id_master_record 
    ) as s 
Pivot (
    max(value_field) 
For 
    id_field In ([1], [2], [3]) 
) As p; 

http://sqlfiddle.com/#!6/f9bca/11

+0

謝謝你,我測試了三個查詢,我得到了類似的時間。然而,我的查詢有輕微的CPU成本,但有更多的嵌套循環,請看http://sqlfiddle.com/#!6/f9bca/10。在我的服務器上,性能沒有任何差異。謝謝 –

0

另一種可能重寫:

SELECT Master.id, Master.data1, Master.data2, 
     u3.value_field AS data3, 
     u4.value_field AS data4, 
     u5.value_field AS data5, 
     ... so for each 
FROM Master 
    LEFT JOIN unknown_fields AS u3 
    ON u3.id_master_record = Master.id 
    AND u3.id_field = 1 
    LEFT JOIN unknown_fields AS u4 
    ON u4.id_master_record = Master.id 
    AND u4.id_field = 2 
    LEFT JOIN unknown_fields AS u5 
    ON u5.id_master_record = Master.id 
    AND u5.id_field = 3 
    ... so for each ; 

如果要優化性能,你應該檢查該執行計劃各種重寫和測試你的數據,在你的服務器。表格上的索引對效率至關重要。聚簇索引的選擇,特別是表unknown_fields也可以影響此查詢。爲unknown_fields

兩個可能的指標是(id_master_record, id_field, value_field)和(不同的訂購):(id_field, id_master_record, value_field)

1

你的初始查詢是做你所需要的一個相當不錯的辦法,而不是我可能建議你尋找到查詢執行計劃,並嘗試提高field_id的索引,也許這會加快你的查詢。