Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Непонятки с внешним запросом / 9 сообщений из 9, страница 1 из 1
07.07.2005, 15:59
    #33155080
BrutSpark
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с внешним запросом
ASE 12.5.0.3

Дано - 2 таблицы a и b, связь между ними - по полю с.
Простая задача - найти записи в т. a, которых нет в b (по полю c)

Так работает правильно, но очень медленно
select a.c
from a
where a.c NOT IN (select c from b)

Так работает неправильно, но быстро.
select a.c
from a, b
where a.c*=b.c
and b.c is null

Почему не правильно - не пойму - этот запрос выбирает ВСЕ записи из таблицы а. Что не так?
...
Рейтинг: 0 / 0
07.07.2005, 16:17
    #33155157
solid
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с внешним запросом
А если в первый запрос добавить distinct быстрее работать не будет?
...
Рейтинг: 0 / 0
07.07.2005, 16:35
    #33155233
BrutSpark
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с внешним запросом
solidА если в первый запрос добавить distinct быстрее работать не будет?

и с distinct и без distinct - дождаться терпения не хватает - пришлось прерывать.
...
Рейтинг: 0 / 0
07.07.2005, 16:36
    #33155241
BrutSpark
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с внешним запросом
solidА если в первый запрос добавить distinct быстрее работать не будет?

Во-вторых я хочу понять, почему 1ый запрос неправильно работает - что не так может быть?
...
Рейтинг: 0 / 0
07.07.2005, 19:23
    #33155644
Peter Kirillow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с внешним запросом
если попробовать так

select aa.c
from a aa
where (select count(*) from b bb where bb.c = aa.c) = 0

ну правда, зачем нам из таблички b тащить весь резалтсет (ведь создаст worktable зараза), чтобы в нем искать вхожнение искомого ?!

еще лучше чтобы по этом полечку был бы индекс, хотя бы в табличке b
...
Рейтинг: 0 / 0
07.07.2005, 21:59
    #33155737
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с внешним запросом
BrutSparkASE 12.5.0.3

Дано - 2 таблицы a и b, связь между ними - по полю с.
Простая задача - найти записи в т. a, которых нет в b (по полю c)

Так работает правильно, но очень медленно
select a.c
from a
where a.c NOT IN (select c from b)


Можно еще
select a.c from a
where not exists ( select * from b where c = a.c)
На счет скорости - нужно чтобы был индекс на c в b.
Но и то запрос будет медленный - он же по всей таблице a.

BrutSpark
Так работает неправильно, но быстро.
select a.c
from a, b
where a.c*=b.c
and b.c is null

Почему не правильно - не пойму - этот запрос выбирает ВСЕ записи из таблицы а. Что не так?


Да, да, да. Вот именно из-за этого и нужны ANSI-OUTER-JOIN-ы. Дело в том, что тут, в старом синтаксисе (TSql outer join) в запросе НЕ ПОНЯТНО, какое поле b.c имеется в виду - ДО соединения (выполнения JOIN-а) таблиц или ПОСЛЕ. А они - разные. ПОСЛЕ это поле может стать "null". Поэтому ASE трактовала эту ситуацию произвольным образом - как решит оптимизатор.
Поэтому сделать вычитание таблиц на TSql outer join невозможно. Нужно использовать ANSI-OUTER-JOIN-ы.

Код: plaintext
1.
2.
3.
select a.c
from a left join b on a.c=b.c
where b.c is null

Но не надейся что это будет работать существенно быстрее.
И строго говоря, запрос неправильный - должно быть

Код: plaintext
1.
2.
3.
select distinct a.c --(или a.*)
from a left join b on a.c=b.c
where b.c is null

А вот наличие DISTINCT делает этот запрос потенциально работающим медленнее, чем вариант с NOT EXISTS.
...
Рейтинг: 0 / 0
08.07.2005, 10:17
    #33156124
BrutSpark
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с внешним запросом
Индексы на с есть и в a, и в b.
Поясню, почему в данном случае я не придаю значения distinct -
потому что для скорости в т. a были уже предварительно отобраны записи
из исходной таблицы именно по distinct. Т.е. в таблице a поле с - на нем индекс - уникальный.
А почему not exists будет работать быстрее, чем NOT IN?
Про OUTER-JOIN теперь понятно, спасибо.
В смысле понятно, что tsql нельзя использовать.
Но непонятно, почему " ПОСЛЕ это поле может стать "null" . Ну да ладно.
А вообще в help-e все так хорошо расписано именно с where - или help устарел?
Еще раз спасибо. :)
...
Рейтинг: 0 / 0
08.07.2005, 10:34
    #33156188
BrutSpark
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с внешним запросом
А все-ж таки дело в чем-то другом - запрос с left join выдает мне опять ПОЛНОСТЬЮ таблицу a.

Вот такой запрос -
select distinct a.c --(или a.*)
from a left join b on a.c=b.c
where b.c is null

опять выдает всю a.
...
Рейтинг: 0 / 0
08.07.2005, 14:30
    #33157027
ozzka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с внешним запросом
Насколько я помню left join (*=) - это же выбор ВСЕХ данных из таблицы слева. А ни в одном запросе (ни в первом, ни в последнем ) на саму таблицу "а" условий не накладывается (они накладываются на "b")
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Непонятки с внешним запросом / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]