Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как ускорить выборку по сложному запросу / 13 сообщений из 13, страница 1 из 1
06.06.2017, 03:38
    #39466310
Водолей
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить выборку по сложному запросу
Привет!
Есть таблица logist отправки товаров по филиалам
ID_TOVAR DATA_OPT KOLVO FROM_OF TO_OF

На каждое поле навешан индекс.
Иногда надо делать выборку товаров, которые были отправлены, например, в течении года и Сызрань и в Кемерово.

Можно использовать что-то типа
select * from logist
where id_tovar in (select id_tovar from logist where to_of='Кемерово' and id_tovar in (select id_tovar from logist where to_of='Сызрань'))
and data_otp>'01.01.2017'

Но подобная конструкция выполняется долго:
1) блок select id_tovar from logist where to_of='Сызрань') выбирает 500 тыс записей за 45 минут
2) select id_tovar from logist where to_of='Кемерово' and id_tovar in (select id_tovar from logist where to_of='Сызрань') отрабатывает за 45 минут

Мне быстрее:
- создать таблицу temp1 для select id_tovar from logist where to_of='Сызрань'
- создать таблицу temp2 для select id_tovar from logist where to_of='Кемерово' and it_tovar in (select id_tovar from temp1)
- сделать select * from logist where id_tovar in (select id_tovar from temp2 ) and data_otp>'01.01.2017'

Можете предложить более правильный или подходящий для данной задачи выход из ситуации. Создавать и удалять временные таблицы тоже не охота.
...
Рейтинг: 0 / 0
06.06.2017, 04:22
    #39466316
Как ускорить выборку по сложному запросу
Водолей,

зри эксплайн
...
Рейтинг: 0 / 0
06.06.2017, 04:43
    #39466317
Как ускорить выборку по сложному запросу
Водолей,

слишком мало вводных. непонятно, а сколько вообще строк в таблице? насколько полная и актуальная статистика по таблице и её индексам присутствует? в какой версии оракла происходит действие и на какой машине. а то может у тебя ноутбук заморенный в качестве сервера, а ты хочешь, чтобы база на нем летала.
ну и про план запроса (для начала) уже озвучили.
...
Рейтинг: 0 / 0
06.06.2017, 05:20
    #39466320
Водолей
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить выборку по сложному запросу
Oracle 10g на Windows 2008 64bit.
Процессор - Intel Xeon 4 ядерный

В таблице ~ 500 млн строк.
Explain plan я делал и от туда я взял 45 минут на выборку записей по индексу.

Статистика полумесячной давности.
...
Рейтинг: 0 / 0
06.06.2017, 05:38
    #39466323
Как ускорить выборку по сложному запросу
ВодолейExplain plan я делал ты к врачу на прием когда придешь, тоже просто скажешь, что анализ крови делал? или всё же результата анализа врачу покажешь?
...
Рейтинг: 0 / 0
06.06.2017, 05:51
    #39466324
Как ускорить выборку по сложному запросу
ВодолейИногда надо делать выборку товаров, которые были отправлены, например, в течении года и Сызрань и в Кемерово.Если интересует информация только за год, то, как минимум, в каждый из IN-подзапросов следовало бы добавить условие, выбирающее данные за интересующий тебя диапазон времени.
Вместо трех заходов в таблицу можно попробовать сделать один, далее аналитикой рассчитать флаг "и в Сызрань, и в Кемерово" и на следующем уровне запроса отфильтровать по этому флагу.

если же охота лазать в таблицу три раза, то попробовать переписать IN-подзапросы на JOIN (возможно, оракл сам не смог этого сделать из-за отсутствия необходимых ограничений по полям таблицы)
...
Рейтинг: 0 / 0
06.06.2017, 05:53
    #39466325
Как ускорить выборку по сложному запросу
Водолей,

как вариант, вместо IN-подзапросов использовать EXISTS. ведь тебя не интересуют ВСЕ поставки товара за год в указанный город. Тебя же интересует лишь факт, что такие поставки имели место быть...
...
Рейтинг: 0 / 0
06.06.2017, 06:12
    #39466328
Как ускорить выборку по сложному запросу
ВодолейМожете предложить более правильный или подходящий для данной задачи выход из ситуации. Создавать и удалять временные таблицы тоже не охота.Можно пробовать двигаться в таких вот направлениях:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
/* Вариант №1 */
select l0.* 
  from logist l0
  join (
         select l1.id_tovar
           from logist l1
          where l1.data_otp > '01.01.2017' -- За такое указание даты - отдельное отрывание рук
            and l1.to_of in ('Кемерово', 'Сызрань')
          group by l1.id_tovar
         having count(distinct l1.to_of) = 2
       ) v
    on l0.id_tovar = v.id_tovar
   and l0.to_of in ('Кемерово', 'Сызрань')
   and l0.data_otp > '01.01.2017'; -- За такое указание даты - отдельное отрывание рук

/* Вариант №2 */
select * 
  from logist l0
 where l0.to_of in ('Кемерово', 'Сызрань')
   and l0.data_otp > '01.01.2017' -- За такое указание даты - отдельное отрывание рук
   and exists (
                select null 
                  from logist l1
                 where l1.data_otp > '01.01.2017' -- За такое указание даты - отдельное отрывание рук
                   and l1.to_of in ('Кемерово', 'Сызрань')
                   and l1.to_of != l0.to_of
                   and l1.id_tovar = l0.id_tovar
              );

/* Вариант №3 */
Select *
  from (
         select l0.* , count(distinct l0.to_of) over(partition by l0.id_tovar) as x_cnt
           from logist l0
          where l0.to_of in ('Кемерово', 'Сызрань')
            and l0.data_otp > '01.01.2017' -- За такое указание даты - отдельное отрывание рук
       )
 where x_cnt = 2;
...
Рейтинг: 0 / 0
06.06.2017, 06:23
    #39466329
Водолей
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить выборку по сложному запросу
Добрый Э - Эх,
Спасибо за развернутый ответ! Про вариант с join тоже думал.
Попробую все три варианта и посмотрю на время выполнения каждого.

P.S. про указание даты. Правильнее так to_date('01.01.2017','dd.mm.yyyy') ?
...
Рейтинг: 0 / 0
06.06.2017, 06:52
    #39466333
Как ускорить выборку по сложному запросу
ВодолейP.S. про указание даты. Правильнее так to_date('01.01.2017','dd.mm.yyyy') ?да. ибо иначе - получаешь NLS-зависимую бомбу замедленного действия.
...
Рейтинг: 0 / 0
06.06.2017, 07:26
    #39466343
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить выборку по сложному запросу
ВодолейKOLVOНа каждое поле навешан индекс.Зачем такому помогать? - Он сам себе стреляет в обе ноги. Всё равно не доползёт.
...
Рейтинг: 0 / 0
06.06.2017, 09:31
    #39466401
MaximaXXL
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить выборку по сложному запросу
Водолей.....................
Иногда надо делать выборку товаров, которые были отправлены, например, в течении года и Сызрань и в Кемерово.

Можно использовать что-то типа
select * from logist
where id_tovar in (select id_tovar from logist where to_of='Кемерово' and id_tovar in (select id_tovar from logist where to_of='Сызрань'))
and data_otp>'01.01.2017'
.................


НЕЛЬЗЯ использовать что-то типа этого
К Вашему селекту постановка должна быть такая: "Найти товар который отправлялся в течении года и при этом он когда-то отправлялся в Кемерово и Сызрань" т.е. товар побывавший в 2001 году в Кемерово и 20016 в Сызрани, а в 2017 был отправлен в Урюпинск попадет в Вашу выборку.

Если Вы хотите сделать выборку по написанному Вами условию воспользуйтесь одним из вариантов который написал Вам Добрый Э - Эх
...
Рейтинг: 0 / 0
06.06.2017, 11:43
    #39466570
Пылинка
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить выборку по сложному запросу
Добрый Э - Эх,
А если 2 запроса с DISTINCT по ключу товара с INTERSECT попробовать, для этих двух городов.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как ускорить выборку по сложному запросу / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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