Подтвердить что ты не робот

Быстрее ли проверять длину = 0, чем сравнивать ее с пустой строкой?

Я слышал, что на некоторых языках программирования быстрее проверить, является ли длина строки 0, чем проверять, является ли контент "". Это также верно для T-SQL?

Пример:

SELECT user_id FROM users WHERE LEN(user_email) = 0

против.

SELECT user_id FROM users WHERE user_email = ''
4b9b3361

Ответ 1

Edit Вы обновили свой вопрос, так как я сначала посмотрел на него. В этом примере я бы сказал, что вы обязательно должны использовать

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

Планы выполнения

Планы выполнения

Оригинальный ответ

В приведенном ниже коде (SQL Server 2008 - я "заимствовал" фреймворк времени из @8kb ответ здесь). У меня было небольшое преимущество для тестирования длины, а не содержимое ниже, когда @stringToTest содержит строку. Они равны таймингам, когда NULL. Я, вероятно, недостаточно проверял, чтобы сделать какие-либо твердые выводы.

В типичном плане выполнения я бы предположил, что разница будет незначительной, и если вы сделаете так много сравнения строк в 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

Я был бы осторожен в использовании 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

Я просто протестировал его в очень ограниченном сценарии и плане выполнения, так что он немного согласуется с его сопоставлением с пустой строкой. (49% - 51%). Это работает с материалами в памяти, хотя это, вероятно, будет отличаться от сравнения с данными из таблицы.

DECLARE @testString nvarchar(max)
SET @testString = ''

SELECT
    1
WHERE
    @testString = ''

SELECT
    1
WHERE
    LEN(@testString) = 0

Изменить: это с SQL Server 2005.