分割字符串的性能最高的方法是什么?

时间:2013-01-31 09:19:36

标签: sql-server performance sql-server-2012 string-split

代码

create table ExampleTable
(
    Name varchar(500)
    CultureCode(5)
)

insert into ExampleTable values('Dit is een test', 'nl-NL')
insert into ExampleTable values('This is a test', 'en-GB')
insert into ExampleTable values('Ceci est un test', 'fr-FR')
insert into ExampleTable values('Dies ist ein Test', 'de-DE')

create procedure GetNameByCultures
(
@CultureCodes varchar(250)
)
as 
begin
//Get ExampleTable items according to the culture codes stated in @CultureCodes
end

- 实例:

CREATE TYPE StringListType AS TABLE
(
    [str] varchar(5) NULL
)

我正在使用MS SQL 2012 V11.0.2100.60

场合

我正在尝试找到提取标签的最佳方式(性能明智)。 我想到的方法,但尚未经过测试的是:

  • 创建用户定义的表格类型,如上所示。

上行:我知道它在数据库上几乎没有表现。

缺点:我必须在存储过程中添加另一个参数。

  • 创建一个用char分隔字符串的函数:','

缺点:我知道在SQL中使用“Right”,“Left”,“Like”和其他varchar转换/编辑属性很慢

UpSide:我可以将处理保留在数据库中。

在目前的情况下,我只在用户定义的表类型中发送一个culturecode。 因此,不可能在此UDTT中添加culturecode,因为您无法将UDTT添加到UDTT。 我唯一的选择是在存储过程中添加另一个参数,这不应该是一个很大的问题......但是我们希望只保留一个参数。

有没有人碰巧知道另一种(更好?)方法,还是应该选择其中一种?

3 个答案:

答案 0 :(得分:0)

我仍然会将文化列表作为逗号分隔的字符串传递,定义一个返回表的函数,然后将此表连接到示例表。只要字符串包含少量元素,您就不会注意到任何性能下降。

如果您能够忍受传递最多N个文化代码的限制,您可以尝试这样的

create procedure GetNameByCulture 
  @CultureInfo varchar(5),
  @CultureInfo1 varchar(5) = null,
  @CultureInfo2 varchar(5) = null
as
 select e.* 
   from ExampleTable e 
        join (
          select @CultureInfo as CultureInfo union
          select @CultureInfo1 union
          select @CultureInfo2
          ) x 
          on e.CultureInfo = x.CultureInfo

我猜这会比字符串版本快一点。但正如我所提到的,无论如何都不会有什么大不了的。

答案 1 :(得分:0)

如何使用replace和cast for xml而不是左/右来分割字符串?

    declare @ExampleTable table
    (
        Name varchar(500),
        CultureCode varchar(5)
    )

    insert into @ExampleTable values('Dit is een test', 'nl-NL')
    insert into @ExampleTable values('This is a test', 'en-GB')
    insert into @ExampleTable values('Ceci est un test', 'fr-FR')
    insert into @ExampleTable values('Dies ist ein Test', 'de-DE')


    declare @CultureCodes varchar(250)
    set @CultureCodes = 'nl-NL,en-GB,fr-FR'

    declare @xml xml
    set @xml = cast('<culturecodes><culture>'+REPLACE(@CultureCodes,',','</culture><culture>')+'</culture></culturecodes>' as xml)

    select 
           C.element.value('.','varchar(max)') as CultureCode_splited
          ,E.CultureCode 
          ,E.name
    from @xml.nodes('/culturecodes/culture')C(element)
    inner join @ExampleTable E
    on E.CultureCode = C.element.value('.','varchar(max)')

结果集看起来像这样......

    CultureCode_splited     CultureCode name
    nl-NL                   nl-NL       Dit is een test
    en-GB                   en-GB       This is a test
    fr-FR                   fr-FR       Ceci est un test

答案 2 :(得分:0)

表值参数是您使用2008年以后的最佳方式。 (See MSDN)。

我完全建议您阅读SQL Server MVP Erland Sommarskog关于可用的不同方法的非常全面的文章,包括分析和性能详细信息。