2010-07-28 17 views
26

He oído que en algunos lenguajes de programación es más rápido verificar si la longitud de una cadena es 0, que verificar si el contenido es "". ¿Esto también es cierto para T-SQL?¿Es más rápido verificar si la longitud = 0 que compararla con una cadena vacía?

muestra:

SELECT user_id FROM users WHERE LEN(user_email) = 0 

vs

SELECT user_id FROM users WHERE user_email = '' 
+0

Estimado ESPO has oído bien, la razón de ser de la cadena se lleva a cabo en la programación idiomas como clase y longitud es la variable de esta clase. Por lo tanto, acceder a una variable es más rápido que ejecutar una función para obtener la respuesta.En sql tiene que llamar a la función para obtener la longitud que es más lenta que la comparación con la cadena vacía o nulo. –

Respuesta

27

Editar Has actualizado tu pregunta desde que miré. En ese ejemplo, diría que definitivamente debe utilizar siempre

SELECT user_id FROM users WHERE user_email = '' 

No

SELECT user_id FROM users WHERE LEN(user_email) = 0 

El primero permitirá un índice que se utilizará. ¡Como optimización del rendimiento, esto prevalecerá sobre la optimización de micro cadenas todo el tiempo! Para ver los planes de esta

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 

Ejecución

Execution Plans

respuesta original

En el siguiente código (SQL Server 2008 - I "prestado" el marco de tiempo de @8kb's answer here) Tengo una ligera ventaja para probar la longitud en lugar de los contenidos a continuación cuando @stringToTest contenía una cadena. Eran sincronizaciones iguales cuando NULL. Sin embargo, probablemente no hice las pruebas suficientes para sacar conclusiones firmes.

En un plan de ejecución típico, me imagino que la diferencia sería insignificante y si está haciendo tanta comparación de cadenas en TSQL que probablemente hará una diferencia significativa, probablemente debería utilizar un lenguaje diferente para ella.

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 
5

Acabo de probar en un plan de escenario y ejecución muy limitado favorece ligeramente comparándola con una cadena vacía. (49% a 51%). Sin embargo, esto está funcionando con cosas en la memoria, por lo que probablemente sería diferente si se compara con los datos de una tabla.

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

SELECT 
    1 
WHERE 
    @testString = '' 

SELECT 
    1 
WHERE 
    LEN(@testString) = 0 

Editar: Esto es con SQL Server 2005.

7

Me gustaría tener cuidado al usar LEN en una cláusula WHERE, ya que podría conducir a la tabla o índice exploraciones.

También tenga en cuenta que si el campo es NULL poder que LEN(NULL) = NULL, por lo que se necesita para definir el comportamiento, por ejemplo:

-- 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 
+0

+1 Me acabo de dar cuenta de eso también. –

Cuestiones relacionadas