表值函数[XML阅读器]非常慢-替代品



我有以下查询,它确实降低了性能,我想知道xml阅读器子查询有什么替代方案。这个查询的目的是用一些html代码导出数据。

表数据的示例如下:

  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/>

我认为你会得到稍微更好的性能,你跳过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用户定义聚合函数进行连接。

在Transact-SQL中连接行值可以找到其他替代方法。

虽然这种替代方法跳过了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引用它。

最新更新