Предложение МЕЖДУ МЕЖДУ <= И> =
Существует ли разница в производительности между использованием предложения BETWEEN или использованием <= AND >= сравнению?
то есть. эти два запроса:
SELECT *
FROM table
WHERE year BETWEEN '2005' AND '2010';
... и
SELECT *
FROM table
WHERE year >= '2005' AND year <= '2010';
В этом примере столбец года VARCHAR2 (4) с индексом на нем.
Ответы
Ответ 1
Не существует разницы в производительности между двумя примерными запросами, потому что BETWEEN
- это просто сокращенный способ выражения диапазона сравнения inclusive. Когда Oracle анализирует условие BETWEEN
, оно автоматически расширяется в отдельные предложения сравнения:
ех.
SELECT *
FROM table
WHERE column BETWEEN :lower_bound AND :upper_bound
... автоматически станет:
SELECT *
FROM table
WHERE :lower_bound <= column
AND :upper_bound >= column
Ответ 2
Нет никакой разницы.
Обратите внимание, что BETWEEN
всегда инклюзивный и чувствительный к порядку аргументов.
BETWEEN '2010' AND '2005'
никогда не будет TRUE
.
Ответ 3
На самом деле это зависит от вашего СУБД.
Некоторые системы управления базами данных будут вычислять дважды ваше выражение (один раз для каждого сравнения) и только один раз, когда вы используете BETWEEN
.
Собственно, если выражение может иметь недетерминированный результат BETWEEN
будет иметь другое поведение, сравните следующее в SQLite:
WHERE RANDOM() BETWEEN x AND y -- one random value generated
WHERE RANDOM() >= x AND RANDOM() <= y -- two distinct random values generated
Это может быть очень трудоемким, если ваше выражение (например) - это подзапрос.
Ответ 4
Если у вас есть сомнения (для Oracle в любом случае), запустите пояснить план, и вы увидите, что оптимизатор хочет сделать. Это относится к большинству вопросов о "существует ли разница в производительности между...". Конечно, есть много других инструментов, но объяснение плана - хорошее начало.
Ответ 5
Он должен быть тем же.
Хороший механизм базы данных будет генерировать тот же план для этого выражения.
Ответ 6
Возможно, стоит рассмотреть стандарт SQL для этого (хотя это может не соответствовать всем реализациям, даже если это необходимо):
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".
Сказав это, нет никакой разницы в поведении, хотя для сложного X
может быть разница во времени разбора, о чем упоминается Benoit здесь
Найдено в http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
Ответ 7
run1 "X >= Y AND X <= Z"
run2 "X МЕЖДУ Y И Z"
Я получаю один Plan hash value
, когда дважды запускаю план объяснения.
Но Tom runStats_pkg получает отличный результат:
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%