Мне нравится версия IN
в ответе Шона.
Обычно можно переписать IN
выражений в выражение, содержащее EXISTS
.Я рассмотрю обе версии здесь и объясню различия.
Во-первых, некоторая преамбула, вот DDL для вашего набора данных:
drop table if exists myTable;
create table myTable (A text, B text, C text);
insert into myTable values ('WN', 'HOU', 'TUL');
insert into myTable values ('AA', 'MCO', 'ORD');
insert into myTable values ('AA', 'DFW', 'DTW');
insert into myTable values ('AA', 'ORD', 'DFW');
insert into myTable values ('F9', 'MCO', 'DTW');
insert into myTable values ('UA', 'LAS', 'LAX');
insert into myTable values ('WN', 'PHX', 'OAK');
insert into myTable values ('OO', 'DTW', 'ESC');
insert into myTable values ('AA', 'LGA', 'DCA');
insert into myTable values ('AA', 'LAX', 'DFW');
create index ix_myTable_001 on myTable (b);
create index ix_myTable_002 on myTable (c);
Вот версия запроса IN
вместе с егоплан выполнения:
SELECT t.a, t.b, t.c
FROM mytable AS t
WHERE t.b = 'DFW' OR t.b IN (SELECT t2.c FROM mytable AS t2 WHERE t2.b = 'DFW');
explain query plan
SELECT t.a, t.b, t.c
FROM mytable AS t
WHERE t.b = 'DFW' OR t.b IN (SELECT t2.c FROM mytable AS t2 WHERE t2.b = 'DFW');
AA|DFW|DTW
OO|DTW|ESC
0|0|0|SEARCH TABLE mytable AS t USING INDEX ix_myTable_001 (b=?)
0|0|0|EXECUTE LIST SUBQUERY 1
1|0|0|SEARCH TABLE mytable AS t2 USING INDEX ix_myTable_001 (b=?)
0|0|0|SEARCH TABLE mytable AS t USING INDEX ix_myTable_001 (b=?)
Вот версия запроса EXISTS
:
select * from myTable T1
where T1.b = 'DFW' OR exists (
SELECT 1
FROM myTable T2
WHERE T2.B = 'DFW'
AND T1.B = T2.C);
explain query plan
select * from myTable T1
where T1.b = 'DFW' OR exists (
SELECT 1
FROM myTable T2
WHERE T2.B = 'DFW'
AND T1.B = T2.C);
AA|DFW|DTW
OO|DTW|ESC
0|0|0|SCAN TABLE myTable AS T1
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 1
1|0|0|SEARCH TABLE myTable AS T2 USING INDEX ix_myTable_002 (c=?)
Обобщение: IN
выражений заставляет подзапрос полностью вычисляться первым перед внешним запросомвыполняет.EXISTS
выражения иногда и внешний запрос, и подзапрос могут оцениваться одновременно.Это означает большую гибкость при выполнении и, возможно, экономию при выполнении и использовании памяти.
Выбор версии IN
по сравнению с версией EXISTS
определяет, будет ли подзапрос генерировать маленький или большой результат.Если он маленький, выберите версию IN
.Если он большой, то перейдите на версию EXISTS
.