代码之家  ›  专栏  ›  技术社区  ›  Espo

检查长度是否为0比将其与空字符串进行比较更快吗?

  •  26
  • Espo  · 技术社区  · 14 年前

    我听说在某些编程语言中,检查字符串的长度是否为 0 ,而不是检查内容是否 "" . 对于T-SQL也是这样吗?

    Sample:

    SELECT user_id FROM users WHERE LEN(user_email) = 0
    

    VS

    SELECT user_id FROM users WHERE user_email = ''
    
    3 回复  |  直到 9 年前
        1
  •  27
  •   Community CDub    7 年前

    编辑 自从我第一次看你的问题后,你就更新了。在这个例子中,我想说的是,你应该始终使用

    select user_id from users where user_email=''
    < /代码> 
    
    

    not

    select user_id from users where len(user_email)=0
    < /代码> 
    
    

    第一个允许使用索引。作为一个性能优化,这将胜过一些字符串微优化每次!看到这个

    select*into temp from[master]。[dbo]。[spt_values]
    
    在temp([名称]、[数字])上创建聚集索引ix
    
    从temp中选择[number],其中[name]=''
    
    从temp中选择[数字],其中len([名称])=0
    < /代码> 
    
    

    执行计划

    原始答案

    在下面的代码中(SQL Server 2008-i“borrowed”the timing framework from@8kb's answer here)当@stringtotestcontained a string时,我得到了测试长度而不是下面内容的轻微边缘。它们在无效时是相等的时间。不过,我可能没有足够的测试来得出任何确切的结论。

    在一个典型的执行计划中,我认为差异可以忽略不计,如果在TSQL中进行如此多的字符串比较,那么它很可能会产生任何显著的差异,您可能应该使用不同的语言来进行比较。

    declare@date datetime2
    声明@testcontents int
    声明@testlength int
    
    设置@testcontents=0
    设置@testlength=0
    
    
    申报
    @计数int,
    值INT,
    @stringtotest varchar(100)
    
    
    设置@stringtotest='jasdsdjkfhjskdhdjsfkjshdjsdhdjfk'
    设置@计数=1
    
    而@count<10000000
    开始
    
    设置@date=getdate()
    当@stringtotest=''时选择@value=case,然后选择1,否则0结束
    设置@testcontents=@testcontents+datediff(微秒,@date,getdate())
    
    设置@date=getdate()
    当len(@stringtotest)=0时选择@value=case,然后选择1,否则选择0结束
    设置@testlength=@testlength+datediff(微秒,@date,getdate())
    
    设置@count=@count+1
    结束
    
    选择
    @测试内容/1000000。作为秒的测试内容,
    @测试长度/1000000。以秒为单位测试长度
    < /代码> 
    S使用

    SELECT user_id FROM users WHERE user_email = ''
    

    不是

    SELECT user_id FROM users WHERE LEN(user_email) = 0
    

    第一个允许使用索引。作为一个性能优化,这将胜过一些字符串微优化每次!看到这个

    SELECT * into #temp FROM [master].[dbo].[spt_values]
    
    CREATE CLUSTERED INDEX ix ON #temp([name],[number])
    
    SELECT [number] FROM #temp WHERE [name] = ''
    
    SELECT [number] FROM #temp WHERE LEN([name]) = 0
    

    执行计划

    Execution Plans

    原始答案

    在下面的代码中(SQL Server 2008-i“借用”了时间框架@8kb's answer here)我在测试长度时有一点优势,而不是下面的内容。@stringToTest包含字符串。它们在无效时是相等的时间。不过,我可能没有足够的测试得出任何确切的结论。

    在一个典型的执行计划中,我认为差异是可以忽略的,如果在TSQL中进行如此多的字符串比较,那么它很可能会产生任何显著的差异,您可能应该对它使用不同的语言。

    DECLARE @date DATETIME2
    DECLARE @testContents INT
    DECLARE @testLength INT
    
    SET @testContents = 0
    SET @testLength = 0
    
    
    DECLARE 
      @count INT,
      @value INT,
      @stringToTest varchar(100)
    
    
    set @stringToTest = 'jasdsdjkfhjskdhdfkjshdfkjsdehdjfk'
    SET @count = 1
    
    WHILE @count < 10000000
    BEGIN
    
      SET @date = GETDATE()
      SELECT @value = CASE WHEN @stringToTest = '' then 1 else 0 end
      SET @testContents = @testContents + DATEDIFF(MICROSECOND, @date, GETDATE())
    
      SET @date = GETDATE()
      SELECT @value = CASE WHEN len(@stringToTest) = 0 then 1 else 0 end
      SET @testLength = @testLength + DATEDIFF(MICROSECOND, @date, GETDATE())
    
      SET @count = @count + 1
    END
    
    SELECT 
      @testContents / 1000000. AS Seconds_TestingContents, 
      @testLength / 1000000. AS Seconds_TestingLength
    
        2
  •  7
  •   StuartLC    11 年前

    我会小心使用 LEN 在一个 WHERE 子句,因为它可能导致表或索引扫描。

    还要注意,如果字段是 NULL 能够 LEN(NULL) = NULL ,因此您需要定义行为,例如:

    -- Cost .33
    select * from [table]
    where itemid = ''
    
    -- Cost .53
    select * from [table]
    where len(itemid) = 0
    
    -- `NULL`able source field (and assuming we treat NULL and '' as the same)
    select * from [table]
    where len(itemid) = 0 or itemid is NULL
    
        3
  •  5
  •   Evil Pigeon    14 年前

    我只是在一个非常有限的场景和执行计划中对它进行了测试,所以有点倾向于将其与空字符串进行比较。(49%至51%)。不过,这是在处理内存中的内容,所以如果与表中的数据进行比较,可能会有所不同。

    DECLARE @testString nvarchar(max)
    SET @testString = ''
    
    SELECT
        1
    WHERE
        @testString = ''
    
    SELECT
        1
    WHERE
        LEN(@testString) = 0
    

    编辑:这是SQL Server 2005。