web-dev-qa-db-fra.com

Clause BETWEEN versus <= AND> =

Existe-t-il une différence de performance entre l'utilisation d'une clause BETWEEN ou l'utilisation de comparaisons <= AND> =?

c'est-à-dire ces deux requêtes:

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

...et

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

Dans cet exemple, la colonne year est VARCHAR2 (4) avec un index.

31
wweicker

Il n’existe aucune différence de performances entre les deux exemples de requête, car BETWEEN est simplement un moyen abrégé d’exprimer une compris comparaison de gamme. Lorsque Oracle analyse la condition BETWEEN, il se transforme automatiquement en clauses de comparaison distinctes:

ex.

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

... deviendra automatiquement:

SELECT *  
  FROM table
 WHERE :lower_bound <= column
   AND :upper_bound >= column
17
wweicker

Il n'y a pas de différence.

Notez que BETWEEN est toujours inclusif et sensible à l'ordre des arguments.

BETWEEN '2010' AND '2005' ne sera jamais TRUE.

26
Quassnoi

En fait, cela dépend de votre moteur de SGBD.

Certains systèmes de gestion de base de données calculent deux fois votre expression (une fois pour chaque comparaison) et une seule fois lorsque vous utilisez BETWEEN.

En fait, si l'expression peut avoir un résultat non déterministe, BETWEEN aura un comportement différent, comparez ce qui suit dans SQLite:

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

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

Cela peut prendre beaucoup de temps si votre expression est (par exemple) une sous-requête.

6
Benoit

En cas de doute (pour Oracle en tout cas), lancez un expliquez le plan et vous verrez ce que l'optimiseur veut faire. Cela s’appliquerait à la plupart des questions sur "Y at-il une différence de performance entre ...". Bien sûr, il existe de nombreux autres outils également, mais expliquer que le plan est un bon début.

2
tbone

Ce devrait être le même.

Un bon moteur de base de données générera le même plan pour cette expression.

1
FolksLord

Cela vaut peut-être la peine d’envisager le standard SQL (bien que ceci pourrait ne pas l'être correspond à toutes les implémentations, même s'il devrait):

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".

Cela dit, il n’ya pas de différence de comportement, bien que pour X complexe, il puisse y avoir une différence de temps d’analyse, comme mentionné par Benoit ici

Trouvé dans http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

1
Lukas Eder

Vous feriez mieux de vérifier vos plans d'exécution car il peut exister des cas Edge étranges où BETWEEN peut avoir un plan d'exécution différent de la combinaison standard> = et <=.

https://blog.pythian.com/Oracle-can-between-and-greater-than-or-qual-to-and-less-than-or-equal-to-differ/

Caveat emptor évidemment. Mais comme les plans d'exécution peuvent changer avec le temps et que je n'ai vraiment pas envie de tester de telles choses, je préfère ne pas utiliser BETWEEN du tout.

Parfois, moins de choix, c'est mieux.

0
luis.espinal

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

run2 "X ENTRE Y ET Z"

J'obtiens un Plan hash value lorsque je lance le plan d'explication deux fois… .. Mais le paquet runStats de Tom obtient un résultat différent:

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%
0
要你命三千