2009-05-28 11 views

Respuesta

23

Puede verificar esto con suficiente facilidad revisando los planes de consulta en ambas situaciones. No hay diferencia de la cual yo sepa. Sin embargo, existe una diferencia lógica entre BETWEEN y "<" y ">" ... BETWEEN es inclusivo. Es equivalente a "< =" y "=>".

+0

Buen punto. Una sutileza que no había notado. –

1

Los dos operadores que se comparan entre sí son fundamentalmente diferentes y, por lo tanto, es probable que los planes de ejecución generados sean diferentes (aunque no garantizados).

El factor determinante es la distribución de datos (selectividad) de la columna a la que se aplican los operadores de comparación. Esto junto con las estadísticas dictará si se usa o no un índice, etc.

Espero que esto tenga sentido.

+0

No estoy seguro exactamente por qué se votó negativamente. ¿Dijo John algo que estaba mal? Alguien que no se siente muy bien? ¿Alguien tiene alguna idea? – wcm

+0

Nunca alteré la pregunta original. Tampoco bajé el voto. –

+0

esta respuesta tiene sentido para mí ... así que este voto negativo es extraño – Michael

0

en realidad. Solo intento verificar con algunos de mis datos. BETWEEN es equivalente a "> =" y "<". Por ejemplo: entre '05/01/2010 'y '05/30/2010': solo obtendrá datos entre 5/1/2010 00:00:00 a 5/29/2010 23:59:59. Intente consultar su tabla con "Ordenar por [TimeField] desc" y verá el resultado.

+3

No, esto es incorrecto. ¿Estás seguro de que tienes datos que son exactamente '5/30/2010 00: 00: 00.000' al milisegundo? –

+0

Esto contradice la documentación, lo que significa que si esto es cierto, es un error. Tiendo a estar de acuerdo con el Sr. Smith en que los datos probablemente sean incorrectos. –

0

También me interesó saber si existe una diferencia de rendimiento cuando utilicé (> = y < =) en comparación con el uso de la palabra clave between. (Vengo de un fondo de dotnet y me gustan los operadores de estilo> =).
Aquí está la escritura que utilicé:

DECLARE 
    @Startdatetime datetime , 
    @Diff int = 0 , 
    @Addrowcount int = 1000; 

SET NOCOUNT ON; 

--Create a tempory table to perform our tests on 

CREATE TABLE dbo.perftest(id smallint NOT NULL 
             IDENTITY(1 , 1) 
             PRIMARY KEY , 
          mytext nvarchar(50)NOT NULL); 

--Now add some sample rows 

SET @Addrowcount = 1000; 

WHILE(@Addrowcount > 0) 

    BEGIN 

     INSERT INTO dbo.perftest(mytext) 
     VALUES('thetext'); 

     SET @Addrowcount = @Addrowcount - 1; 

    END; 

SELECT @Startdatetime = GETDATE(); 

-- do method 1 here 

SELECT mytext 
    FROM dbo.perftest 
    WHERE(id >= 100) 
    AND (id <= 900); 

--end method1 

SELECT @Diff = DATEDIFF(millisecond , @Startdatetime , GETDATE()); 

PRINT ':Method 1: ' + CAST(@Diff AS nvarchar(20)) + ' ms'; 

--reset start time 

SELECT @Startdatetime = GETDATE(); 

--do method2 here 

SELECT mytext 
    FROM dbo.perftest 
    WHERE id BETWEEN 100 
    AND 900; 

--end method2 

SELECT @Diff = DATEDIFF(millisecond , @Startdatetime , GETDATE()); 

PRINT ':Method 2: ' + CAST(@Diff AS nvarchar(20)) + ' ms'; 

Los resultados fueron los siguientes:

Método 1: 140 ms

Método 2: 70 ms

lo que parece que el rendimiento se mejora al usar entre.

+0

No estoy seguro de la validez de una prueba como esta ... Supongo que es tan válida como cualquier prueba de perfil simple, pero eso no dice mucho. Puede ser muy diferente basado en el almacenamiento en caché (acaba de agregar los registros) y nada más sucede en ese momento (a diferencia de un servidor del mundo real) y todos los registros se agregan al mismo tiempo, vs fragmentados en varias páginas/tiempo . – eselk

1

Me encanta cuando la gente da el código para hacer sus propias pruebas, necesita hacer un subconjunto más grande/prueba repetida para tener en cuenta los índices que se cargan en la memoria, etc ... antes de sacar conclusiones precipitadas. Aquí es el mismo código con una mesa más grande y 10 iteraciones

DECLARE 
    @Startdatetime datetime , 
    @Diff int = 0 , 
    @Addrowcount int = 1000 , 
    @ptr int = 1; 


SET NOCOUNT ON; 

--Create a tempory table to perform our tests on 
DROP TABLE dbo.perftest 

CREATE TABLE dbo.perftest(id int NOT NULL 
             IDENTITY(1 , 1) 
             PRIMARY KEY , 
          mytext nvarchar(50)NOT NULL); 

--Now add some sample rows 

SET @Addrowcount = 20000; 

WHILE(@Addrowcount > 0) 

    BEGIN 

     INSERT INTO dbo.perftest(mytext) 
     VALUES('thetext'); 

     SET @Addrowcount = @Addrowcount - 1; 

    END; 

WHILE @ptr < 10 -- do this a few times to account for indexes being loaded into memory 

BEGIN 

    SELECT @Startdatetime = GETDATE(); 

    -- do method 1 here 

    SELECT mytext 
     FROM dbo.perftest 
     WHERE(id >= (100 + (@ptr * 1000))) 
     AND (id <= (500 + (@ptr * 1000))); 

    --end method1 

    SELECT @Diff = DATEDIFF(millisecond , @Startdatetime , GETDATE()); 

    PRINT ':Method 1: ' + CAST(@Diff AS nvarchar(20)) + ' ms'; 

    --reset start time 

    SELECT @Startdatetime = GETDATE(); 

    --do method2 here 

    SELECT mytext 
     FROM dbo.perftest 
     WHERE id BETWEEN (300 + (@ptr * 1000)) 
     AND (800 + (@ptr * 1000)); 

    --end method2 

    SELECT @Diff = DATEDIFF(millisecond , @Startdatetime , GETDATE()); 

    PRINT ':Method 2: ' + CAST(@Diff AS nvarchar(20)) + ' ms'; 

    SET @ptr = @ptr + 1 

END 

le da un conjunto muy diferente de resultados:

--Method 1 -- 10 ms 
--Method 2 -- 33 ms 
--Method 1 -- 40 ms 
--Method 2 -- 26 ms 
--Method 1 -- 23 ms 
--Method 2 -- 23 ms 
--Method 1 -- 13 ms 
--Method 2 -- 16 ms 
--Method 1 -- 13 ms 
--Method 2 -- 20 ms 
--Method 1 -- 6 ms 
--Method 2 -- 16 ms 
--Method 1 -- 26 ms 
--Method 2 -- 16 ms 
--Method 1 -- 13 ms 
--Method 2 -- 13 ms 
--Method 1 -- 16 ms 
--Method 2 -- 13 ms 

diría de esto (todavía bastante poco científico) de prueba, no hay mucha diferencia de cualquier manera.

4

motor La consulta realiza la conversión entre en >= y <= (echar un vistazo al plan de consulta) por lo que en la práctica ellos son idénticos y, en teoría, >= <= es más rápido debido a que el motor no tendrá que traducir. Buena suerte notando una diferencia sin embargo.

utilizo entre todos modos, me parece que lee más fácil

consultas

muy complejas/vistas anidadas con numerosas comparaciones entre podrían beneficiarse de transformarse en >= <= ya que esto podría potencialmente evitar tiempos de espera de optimización mediante la reducción del tiempo dedicado a la refactorización la consulta (sólo una teoría, no probado por mí & Nunca lo he notado)

Cuestiones relacionadas