2011-01-26 13 views
26

¿Existe una diferencia de rendimiento entre el uso de una cláusula BETWEEN o el uso de < = AND> = comparaciones?BETWEEN cláusula versus <= AND > =

es decir, estas dos consultas:

SELECT * 
    FROM table 
WHERE year BETWEEN '2005' AND '2010'; 

... y

SELECT * 
    FROM table 
WHERE year >= '2005' AND year <= '2010'; 

En este ejemplo, la columna de la años es VARCHAR2 (4) con un índice en él.

+4

No utilizaría una cadena como '' 2005'' filtrar años o fechas, sin embargo. –

Respuesta

16

No hay diferencia de rendimiento entre las dos consultas de ejemplo porque BETWEEN es simplemente una forma abreviada de expresar una comparación de rango inclusive. Cuando Oracle analiza la condición BETWEEN se expandirá automáticamente en cláusulas de comparación separadas:

ex.

SELECT * 
    FROM table 
WHERE column BETWEEN :lower_bound AND :upper_bound 

... se convertirá automáticamente:

SELECT * 
    FROM table 
WHERE :lower_bound <= column 
    AND :upper_bound >= column 
+10

@rsenna: No, publiqué esta pregunta para almacenar la información aquí porque alguien en nuestra oficina me preguntó esto y me di cuenta al buscar que nadie más había preguntado aquí antes. Es mi contribución de conocimiento al mundo por el día y es un uso válido del servicio según las preguntas frecuentes y la declaración de la misión. Tenía la intención de preguntar, responder y aceptar mi respuesta todo en 10 segundos, pero el sistema no me dejaba aceptar mi propia respuesta tan rápido para que otras personas comenzaran a responder también ... – wweicker

+1

Oye, no hay problema. De hecho, SO oficialmente [aprueba] (http://meta.stackexchange.com/questions/12513/should-i-not-answer-my-own-questions) dicho comportamiento ... – rsenna

+0

@rsenna: ¡Exactamente! :) Gracias por desenterrar ese enlace, y para explicar mejor el escenario me olvidé de que tienes que [esperar dos días para responder tu propia pregunta] (http://blog.stackoverflow.com/2009/01/accept-your -own-answers /) ... – wweicker

22

No hay ninguna diferencia.

Tenga en cuenta que BETWEEN es siempre inclusivo y sensible al orden de los argumentos.

BETWEEN '2010' AND '2005' nunca será TRUE.

+1

Depende del sistema RDBMS subyacente. SQL-92 dice que _ "X ENTRE YY Z" es equivalente a "X> = YY X <= Z" _ pero no todos los proveedores se dirigen a esa línea. SQL Server, por ejemplo, no lo hace. –

+0

@Nicholas: mire las etiquetas de pregunta. En cuanto a su comentario 'SQL Server', ¿podría proporcionar una referencia? – Quassnoi

+0

A menos que hayan ajustado las cosas para entre, el orden no es importante. Sin embargo, no puedo decir que lo haya probado recientemente. Habiendo sido quemado en eso antes, si el orden es crítico para una prueba, hago la prueba de prueba explícita con '> =' y '<='. –

5

Actualmente depende de su motor DBMS.

Algunos sistemas de administración de bases de datos calculan el doble de su expresión (una para cada comparación), y solo una vez cuando usa BETWEEN.

En realidad, si la expresión puede tener un resultado no determinista BETWEEN tendrá un comportamiento diferente, comparativa in SQLite:

WHERE RANDOM() BETWEEN x AND y -- one random value generated 

WHERE RANDOM() >= x AND RANDOM() <= y -- two distinct random values generated 

Esto puede llevar mucho tiempo si su expresión es (por ejemplo) una subconsulta.

+0

Pensamiento interesante ... ¿Puedes dar un ejemplo para esto? ¿Para qué base de datos experimentó eso? –

+0

@LukasEder: vea el ejemplo – Benoit

+0

Hmm, buen pensamiento. Eso deja algunas preguntas abiertas con respecto al [estándar SQL] (http://stackoverflow.com/a/9680753/521799), y si es realmente posible afirmar que las dos expresiones son equivalentes –

2

En caso de duda (para Oracle de todos modos), ejecute un explain plan y verá lo que el optimizador quiere hacer. Esto se aplicaría a la mayoría de las preguntas sobre "¿hay una diferencia de rendimiento entre ...". Por supuesto, hay muchas otras herramientas también, pero explican que el plan es un buen comienzo.

1

Es debería ser lo mismo.

Un buen motor de base de datos generará el mismo plan para esa expresión.

+0

sí, mi comentario fue más genérico que esta situación específica. Enseña a un hombre a pescar ... – tbone

0

Puede ser vale la pena considerar el estándar SQL para esto (aunque esto podría no corresponden a todas las implementaciones, incluso si debe):

Format 

<between predicate> ::= 
    <row value constructor> [ NOT ] BETWEEN 
    <row value constructor> AND <row value constructor> 

Syntax Rules 

[...] 

6) "X BETWEEN Y AND Z" is equivalent to "X>=Y AND X<=Z". 

Dicho esto, no hay ninguna diferencia en comportamiento, aunque para el complejo X, puede haber una diferencia en el tiempo de análisis, como se ha mencionado por Benoit here

encontrados en http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

0

run1 "X> = Y y X = Z <"

Run2 "X entre Y y Z"

consigo uno Plan hash value cuando corro explicar el plan dos veces. Pero runStats_pkg de Tom obtener un resultado diffent:

Run1 ran in 1 cpu hsecs 
Run2 ran in 1 cpu hsecs 
run 1 ran in 100% of the time 

Name      Run1 Run2  Diff 
STAT...recursive calls   12  13  1 
STAT...CPU used by this sessio  2  3  1 
STAT...physical read total IO  0  1  1 
STAT...consistent gets   18  19  1 
... 
... 
LATCH.row cache objects   44,375 1,121  -43,254 
LATCH.cache buffers chains  68,814 1,397  -67,417 
STAT...logical read bytes from  655,360  573,440  -81,920 
STAT...session uga memory max  123,512  0 -123,512 
STAT...session pga memory  262,144 65,536 -196,608 
STAT...session pga memory max  262,144 65,536 -196,608 
STAT...session uga memory  -327,440 65,488  392,928 

Run1 latches total versus runs -- difference and pct 
Run1  Run2 Diff  Pct 
203,927  28,673 -175,254 711.22% 
Cuestiones relacionadas