Непонятки с запросом или я туплю :)

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
ponyol
Сообщения: 26
Зарегистрирован: 16 мар 2005, 17:08

Непонятки с запросом или я туплю :)

Сообщение ponyol » 16 мар 2005, 17:17

Доброго дня!

Вот запрос:

Код: Выделить всё

select distinct a.fone from atc a
where a.fone like '8067%'
or a.fone like '8097%'
or a.fone like '8050%'
or a.fone like '8066%'
выдает около 800 записей (в таблице 47000) за секунду.
А вот этот:

Код: Выделить всё

select b.fone
from atc b
where b.i_date >= '01.02.2005'
and b.i_date < '01.03.2005'
and b.fone in (select distinct a.fone from atc a
where a.fone like '8067%'
or a.fone like '8097%'
or a.fone like '8050%'
or a.fone like '8066%')
зависает навсегда :(.

Что это? Вроде в запросе все нормально или я переработал?

ЗЫ. У меня fb 1.5.2

ponyol
Сообщения: 26
Зарегистрирован: 16 мар 2005, 17:08

Непонятки с запросом или я туплю :)

Сообщение ponyol » 16 мар 2005, 17:29

Может этот (второй) запрос надо по другому писать?

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 16 мар 2005, 18:25

а зачем тебе DISTINCT в подзапросе?

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Re: Непонятки с запросом или я туплю :)

Сообщение Merlin » 16 мар 2005, 18:38

А вот этот?

Код: Выделить всё

select distinct a.fone from atc a
where
where a.i_date >= '01.02.2005'
and a.i_date < '01.03.2005'
And
(a.fone like '8067%'
or a.fone like '8097%'
or a.fone like '8050%'
or a.fone like '8066%')
:lol:

ponyol
Сообщения: 26
Зарегистрирован: 16 мар 2005, 17:08

Сообщение ponyol » 16 мар 2005, 18:43

dimitr писал(а):а зачем тебе DISTINCT в подзапросе?
Чтобы выбранные телефонные номера не повторялись :), т.е. чтобы внешний запрос не напрягался сильно.

ЗЫ. Если внешний запрос запустиь без подзапроса, то получается около 4500 записей. Неужели fb в них так долго ищет "b.fone in"? Или я ничего не понимаю?

ponyol
Сообщения: 26
Зарегистрирован: 16 мар 2005, 17:08

Re: Непонятки с запросом или я туплю :)

Сообщение ponyol » 16 мар 2005, 18:49

Merlin писал(а):А вот этот?

select distinct a.fone from atc a
where
where a.i_date >= '01.02.2005'
and a.i_date < '01.03.2005'
And
(a.fone like '8067%'
or a.fone like '8097%'
or a.fone like '8050%'
or a.fone like '8066%')

:lol:
ОПА :). А я и не знал, что такая конструкция прокатывает, вернее не предпологал :(. Большое спасибо, так все работает быстро!

ЗЫ. Но все же, ради любопытства, почему же мой запрос так тормозит?

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 17 мар 2005, 10:43

ponyol писал(а):
dimitr писал(а):а зачем тебе DISTINCT в подзапросе?
Чтобы выбранные телефонные номера не повторялись :), т.е. чтобы внешний запрос не напрягался сильно.
А ты бы попробовал, а не думал :) Если индекс по a.fone есть, конечно.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Re: Непонятки с запросом или я туплю :)

Сообщение Merlin » 17 мар 2005, 13:12

ponyol писал(а): ЗЫ. Но все же, ради любопытства, почему же мой запрос так тормозит?
Потому что его попросил ограничить выборку датами, а потом для каждой записи этой выборки сделать подзапрос и большую часть из неё выкинуть, вместо того, чтобы наложить все ограничения сразу.

ponyol
Сообщения: 26
Зарегистрирован: 16 мар 2005, 17:08

Re: Непонятки с запросом или я туплю :)

Сообщение ponyol » 18 мар 2005, 21:22

Merlin писал(а):
ponyol писал(а): ЗЫ. Но все же, ради любопытства, почему же мой запрос так тормозит?
Потому что его попросил ограничить выборку датами, а потом для каждой записи этой выборки сделать подзапрос и большую часть из неё выкинуть, вместо того, чтобы наложить все ограничения сразу.
Дело в том, что выборка по датам дает всего лишь 3800 записей. Т.е. сервер из этого количества выберает 800 записей и чуть ли не умирает (99% проца и бесконечное время)? Питон с такой задачей (скриптом из десятка строк) справляется ну очень быстро (не засекал)! У меня есть ощущение, что fb сначала пытается выгрибать записи по всей таблице из подзапроса, а потом по датам. По другому эту тормознутось я объяснить не могу.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Re: Непонятки с запросом или я туплю :)

Сообщение Merlin » 18 мар 2005, 22:51

ponyol писал(а):
Merlin писал(а):
ponyol писал(а): ЗЫ. Но все же, ради любопытства, почему же мой запрос так тормозит?
Потому что его попросил ограничить выборку датами, а потом для каждой записи этой выборки сделать подзапрос и большую часть из неё выкинуть, вместо того, чтобы наложить все ограничения сразу.
Дело в том, что выборка по датам дает всего лишь 3800 записей. Т.е. сервер из этого количества выберает 800 записей и чуть ли не умирает (99% проца и бесконечное время)? Питон с такой задачей (скриптом из десятка строк) справляется ну очень быстро (не засекал)! У меня есть ощущение, что fb сначала пытается выгрибать записи по всей таблице из подзапроса, а потом по датам. По другому эту тормознутось я объяснить не могу.
От упэртый, як хохол :) Если бы так, то было бы как раз быстрее. А ты его заставил ограничить по дате, а потом 3800 раз
ponyol писал(а): выгрибать записи по всей таблице из подзапроса

eugeney
Сообщения: 79
Зарегистрирован: 29 окт 2004, 18:51

Сообщение eugeney » 19 мар 2005, 12:56

ponyol писал(а):
dimitr писал(а):а зачем тебе DISTINCT в подзапросе?
Чтобы выбранные телефонные номера не повторялись :), т.е. чтобы внешний запрос не напрягался сильно.

ЗЫ. Если внешний запрос запустиь без подзапроса, то получается около 4500 записей. Неужели fb в них так долго ищет "b.fone in"? Или я ничего не понимаю?
Не понимаеш. FB выполняет подзапрос каждый раз для проверки in. Что приводит к 4500 раз выполнению подзапроса.

ponyol
Сообщения: 26
Зарегистрирован: 16 мар 2005, 17:08

Сообщение ponyol » 19 мар 2005, 13:26

eugeney писал(а): Не понимаеш. FB выполняет подзапрос каждый раз для проверки in. Что приводит к 4500 раз выполнению подзапроса.
Так бы сразу и сказали :). Теперь понимаю. Я, несмышленышь, думал, что in выполняется только один раз (а почему бы не один?) и висит где нить в кеше. Странно, что не так :).

eugeney
Сообщения: 79
Зарегистрирован: 29 окт 2004, 18:51

Сообщение eugeney » 19 мар 2005, 16:44

ponyol писал(а): а почему бы не один?
Странно, что не так :).
Не все так просто. Изза наличия selectable procedure запросы получаються не реентабелные. Т.е. ты можеш выполнить запрос

select ... from table1 join sp1(table1.field2) on 1=1
Вот и получается что sp1 будет вызванна по количеству записей в таблице.
Тоже самое и по процедурам.

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 19 мар 2005, 21:40

ponyol писал(а):Я, несмышленышь, думал, что in выполняется только один раз (а почему бы не один?) и висит где нить в кеше. Странно, что не так :).
Подзапрос сервер превращает в коррелированный, с зависимостью от внешнего через b.fone. Но ты серверу всю бодягу испортил своими условиями отбора и DISTINCT-ом сверху, который просто блокирует возможный индексный поиск по fone.

ponyol
Сообщения: 26
Зарегистрирован: 16 мар 2005, 17:08

Сообщение ponyol » 21 мар 2005, 14:00

Хорошо, все понял. Будем повышать уровень знаний.
Всем спасибо, тема закрыта.

Ответить