#5 09.04.06 21:09
Re: [SQL] field IN(A..B) versus field>=A AND field <=B
where a in (b,c,d) разворачивается в where (a = b) or (a = c) or (a = d)
в итоге, при использовании <=> получается 2 сравнения на каждую запиcь (проверяется принадлежность интервалу, краткая запись =between), при использовании IN от 1(a = b) до 3-х (a not in(b,c,d)) проверок на каждую извлекаемую запись.
а вообще все зависит от реализации sql и нужно делать в соответствии с логикой, остальное пусть делает интерпретатор. для интервалов - between.
Offline
#10 10.04.06 11:00
#11 10.04.06 11:01
#12 10.04.06 11:01
#13 10.04.06 11:36
Re: [SQL] field IN(A..B) versus field>=A AND field <=B
XuMiX написал(а):
Мерзкий, если полей много, и в таблице полей много, то почему бы и не написать так. Тут минус только один будет - читаемость кода ухудшается.
потому что не факт, что завтра в таблице полей не добавится, зачем тащить лишнее на клиента?
Offline
#14 10.04.06 12:29
#15 10.04.06 15:46
#16 10.04.06 15:57
#17 13.04.06 12:21
Re: [SQL] field IN(A..B) versus field>=A AND field <=B
Matrim написал(а):
where a in (b,c,d) разворачивается в where (a = b) or (a = c) or (a = d)
в итоге, при использовании <=> получается 2 сравнения на каждую запиcь (проверяется принадлежность интервалу, краткая запись =between), при использовании IN от 1(a = b) до 3-х (a not in(b,c,d)) проверок на каждую извлекаемую запись.
а вообще все зависит от реализации sql и нужно делать в соответствии с логикой, остальное пусть делает интерпретатор. для интервалов - between.
Добавлю, что разнича есть в зависимости от того проиндексировано поле на которое накладывается условие или нет.
Пример (под Oracle):
SQL> create table tt as select * from all_objects;
Таблица создана.
Сначала с индексом:
SQL> create index tt_idx on tt(object_id);
Индекс создан.
SQL> set autotrace traceonly
SQL> select count(*) from tt where object_id in (100,101,102,103,104,105);
Затрач.время: 00:00:00.01
План выполнения
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 CONCATENATION
3 2 INDEX (RANGE SCAN) OF 'TT_IDX' (NON-UNIQUE)
4 2 INDEX (RANGE SCAN) OF 'TT_IDX' (NON-UNIQUE)
5 2 INDEX (RANGE SCAN) OF 'TT_IDX' (NON-UNIQUE)
6 2 INDEX (RANGE SCAN) OF 'TT_IDX' (NON-UNIQUE)
7 2 INDEX (RANGE SCAN) OF 'TT_IDX' (NON-UNIQUE)
8 2 INDEX (RANGE SCAN) OF 'TT_IDX' (NON-UNIQUE)
Статистика
----------------------------------------------------------
0 recursive calls
0 db block gets
12 consistent gets
0 physical reads
SQL> select count(*) from tt where object_id between 100 and 105;
Затрач.время: 00:00:00.01
План выполнения
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 INDEX (RANGE SCAN) OF 'TT_IDX' (NON-UNIQUE)
Статистика
----------------------------------------------------------
0 recursive calls
0 db block gets
2 consistent gets
0 physical reads
Теперь без индекса по этому полю:
SQL> drop index tt_idx;
Индекс удален.
SQL> select count(*) from tt where object_id in (100,101,102,103,104,105);
COUNT(*)
----------
0
План выполнения
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'TT'
Статистика
----------------------------------------------------------
0 recursive calls
0 db block gets
341 consistent gets
0 physical reads
SQL> select count(*) from tt where object_id between 100 and 105;
COUNT(*)
----------
0
План выполнения
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'TT'
Статистика
----------------------------------------------------------
0 recursive calls
0 db block gets
341 consistent gets
0 physical reads
Offline

