2011-08-12 41 views
2

我有以下查詢,真正殺死性能,並想知道什麼替代他們是一個XML閱讀器子查詢。這個查詢的目的是用一些html代碼導出數據。表值函數[XML讀取器]非常慢 - 替代方法?

表數據的一個例子如下。

p_s_id | p_c_id | notes 
    ----------------------- 
    1 | 1 | this note is really long. 
    2 | 1 | This is fun. 
    3 | null | long note here 
    4 | 2 | this is not fun 
    5 | 2 | this is not fun 
    6 | 3 | long note here 

我想採取所有具有相同p_c_id的不同音符並將它們連接在一起,如下所示。

可以提供任何其他信息,以便隨時發表評論。

select distinct 
    p_c_id 
    ,'<br/><br/>'+(select distinct '&bull; ' +cast(note as nvarchar(max)) + ' <br/> ' 
     from dbo.spec_notes_join m2 
     where m.p_c_id = m2.p_c_id 
     and isnull(note,'') <> '' 
     for xml path(''), type).value('.[1]', 'nvarchar(max)') as notes_spec 
from dbo.spec_notes_join m 

所以出口將如下所示:

p_c_id | notes 
-------------- 
    1 | <br/><br/> &bull; this note is really long. <br/> &bull This is fun <br/> 
    2 | <br/><br/> &bull; This is not fun. <br/> 
    3 | <br/><br/> &bull; long note here. <br/> 

回答

3

我認爲你會得到略好的性能,你可以跳過外部查詢中的distinct並改爲執行group by p_c_id

select p_c_id, 
     '<br/><br/>'+(select distinct '&bull; ' +cast(note as nvarchar(max)) + ' <br/> ' 
        from dbo.spec_notes_join m2 
        where m.p_c_id = m2.p_c_id and 
          isnull(note,'') <> '' 
        for xml path(''), type).value('.', 'nvarchar(max)') as notes_spec 
from dbo.spec_notes_join m  
group by p_c_id 

您也可以嘗試連接CLR User-Defined Aggregate Function

其他替代品可以在這裏找到Concatenating Row Values in Transact-SQL

+0

表現要好得多。 –

+0

CLR是迄今爲止最好的選擇。對不起,我沒有澄清過。 –

3

雖然這一備選方案跳過了XML,我不知道這是否可以提高性能,如果你能測和後結果爲註釋,我會讚賞它。 (它的工作對我的快速模擬,你可能需要做你自己的結構一些輕微的調試。)

開始使用此項功能:

CREATE FUNCTION dbo.Testing 
(
    @p_c_id int 
) 
RETURNS varchar(max) 
AS 
BEGIN 
    DECLARE @ReturnString varchar(max) 

    SELECT @ReturnString = isnull(@ReturnString + ' <br/> , <br/><br/>&bull; ', '<br/><br/>&bull; ') + Name 
    from (select distinct note 
      from spec_notes_join 
      where p_c_id = @p_c_id 
      and isnull(note, '') <> '') xx 

    SET @ReturnString = @ReturnString + ' <br/> ' 

    RETURN @ReturnString 
END 
GO 

,然後將其嵌入到您的查詢:

SELECT p_c_id, dbo.Testing(p_c_id) 
from (select distinct p_c_id 
     from dbo.spec_notes_join) xx 

由於每行所需的函數,這可能表現不佳。可能更快的變體是將該函數編寫爲表值函數,並在連接子句中通過CROSS APPLY來引用它。

+0

表現好得多,但我選擇的答案工作得更快。希望我可以選擇兩個。謝謝。 –