Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Помогите ускорит выборку данных  [new]
Зурбаган
Member

Откуда:
Сообщений: 80
Привет!
Имеется у меня БД движения и поступления товаров на базу хранения. Такого вида таблица main

ID Froms Tos Date Id_Partia_towara Quantity
1 Stambul Moscow 10/03/2015 5 500
2 Sofia Moscow 16/08/2015 15 100
3 Moscow Omsk 11/03/2015 5 250
4 Moscow Belgorod 12/03/2015 5 250


Надо выбрать партии товаров, которые пришли в москву на склад, пробыли там не более 2 дней и ушли в регионы.
Я делаю запрос
select * from main where id_partia_towara in (select id_partia_towara from main where froms='Moscow')

, потом анализирую в полученном массиве то, сколько товар пробыл в Москве.

Вышеприведенный запрос очень долго выполняется, хотя поле id_partia_towara индексное поле. Как можно ускорить данный запрос?
20 мар 16, 15:56    [18955562]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
ora601
Member

Откуда:
Сообщений: 750
Зурбаган
хотя поле id_partia_towara индексное поле


А поле Froms? (а может Forms ? :) Ну кто так называет поля таблицы... )
20 мар 16, 16:08    [18955581]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
Зурбаган
Member

Откуда:
Сообщений: 80
ora601,
Нормально у меня поля названы, это я для примера набросал таблицу.
Да, помимо индекса на ID, имеется составной индекс на Froms и Tos (Из - В)
20 мар 16, 16:50    [18955675]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
dmdmdm
Member

Откуда: Нижний Новгород
Сообщений: 1635
Зурбаган
имеется составной индекс на Froms и Tos (Из - В)


Что посмотреть надо, чтоб понять, используется ли он?
Слово на букву "п".
20 мар 16, 17:10    [18955700]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
Зурбаган
Member

Откуда:
Сообщений: 80
dmdmdm,
план работы скрипта :)
Индексы используются, просто объем данных таков, что в подзапросе большая выборка получается.
20 мар 16, 17:15    [18955708]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10040
Зурбаган,

А зачем where id_partia_towara in (select id_partia_towara from main where froms='Moscow') если поле froms денормализировано и имеется в main? Почему не:

select * from main where froms='Moscow'

SY.
20 мар 16, 17:33    [18955730]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
dmdmdm
Member

Откуда: Нижний Новгород
Сообщений: 1635
Подзапрос тут вообще не нужен.
И когда дело касается точных данных, неплохо бы их приводить.
Не "что-то долго работает", а "работает 10 с на таблице в 10 млн. строк с таким-то планом". Можно еще уточнять, на каком железе, если уж оно сильно старое.
20 мар 16, 17:35    [18955731]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
dmdmdm
Member

Откуда: Нижний Новгород
Сообщений: 1635
И неплохо бы сказать, сколько строк в результате получается, и что с ними потом происходит.
А то, может, вы с сервера выкачиваете 30% большой таблицы и потом ее в клиентском приложении анализируете.
20 мар 16, 17:48    [18955756]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
Зурбаган
Member

Откуда:
Сообщений: 80
Ok, приношу извинения, если дал не полную картину происходящего.

БД реализована на oracle 10g. На сервере xion 32 Гб оперативы.

Таблица main парnирнированная, с локальными индексами. Строк за все года ~ 2 млрд.
В подзапросе за период в один год получается ~ 10-15 млн записей. Потом по их id еще делается одна выборка.
Запрос выполняется только на стороне сервера, клиентских приложений нет.
20 мар 16, 17:53    [18955766]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
ora601
Member

Откуда:
Сообщений: 750
Зурбаган
Ok, приношу извинения, если дал не полную картину происходящего.

БД реализована на oracle 10g. На сервере xion 32 Гб оперативы.

Таблица main парnирнированная, с локальными индексами. Строк за все года ~ 2 млрд.
В подзапросе за период в один год получается ~ 10-15 млн записей. Потом по их id еще делается одна выборка.
Запрос выполняется только на стороне сервера, клиентских приложений нет.


План нужно показать, лучше со статистиками.
20 мар 16, 17:57    [18955773]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
dmdmdm
Member

Откуда: Нижний Новгород
Сообщений: 1635
Еще раз - сколько конкретно выполняется запрос. План.
Далее встает вопрос целесообразности. Если это отчет "на один раз", то мне лично пофигу, будет он выполняться 1 с или 1 час.
А если он регулярный, то такие вопросы в системах учета опираются на заранее сформированные агрегированные данные (регистры).
20 мар 16, 18:05    [18955787]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
dmdmdm
Member

Откуда: Нижний Новгород
Сообщений: 1635
А еще очень неплохо - подготовить test case.
И сам все лучше поймешь, и к участникам обсуждения уважение проявишь.
Вот я 10 минут потратил. Без партиционирования, конечно.
+
create table test(ID number,  Froms varchar2(50),  Tos varchar2(50),  Date1 date,  Id_Partia_towara number,  Quantity number);
create table cities(id number, cityname varchar2(50));

insert into CITIES (ID, CITYNAME)
values (1, 'Moscow');

insert into CITIES (ID, CITYNAME)
values (2, 'Sofia');

insert into CITIES (ID, CITYNAME)
values (3, 'Stambul');

insert into CITIES (ID, CITYNAME)
values (0, 'DefaultCity');

insert into CITIES (ID, CITYNAME)
values (4, 'Omsk');

insert into CITIES (ID, CITYNAME)
values (5, 'Belgorod');

insert into CITIES (ID, CITYNAME)
values (6, 'Paris');

insert into CITIES (ID, CITYNAME)
values (7, 'New York');

insert into CITIES (ID, CITYNAME)
values (8, 'Tegusigalpa');

insert into CITIES (ID, CITYNAME)
values (9, 'Tokio');

insert into CITIES (ID, CITYNAME)
values (10, 'Sydney');
commit;


begin
for i in 1..1e6 loop
  insert into test
    (id, froms, tos, date1, id_partia_towara, quantity)
  values
    (round(dbms_random.value*1e8, 0), (select cityname from cities where id= (select round(dbms_random.value*10, 0) from dual)), 
       (select cityname from cities where id= (select round(dbms_random.value*10, 0) from dual)), sysdate-1000+round(dbms_random.value*1000, 0),
        round(dbms_random.value*1e6, 0), round(dbms_random.value*1e5/100, 0)*100);
end loop;  
end;
/

create index ind1 on TEST (id_partia_towara);
create index ind2 on TEST (froms, tos);

analyze table test estimate statistics;

  
select * from test where id_partia_towara in (select id_partia_towara from test where froms='Moscow')



На моих данных Table access full.
Дальше можно анализировать, почему. Низкая селективность, небольшой размер таблицы (тоже нет смысла индекс использовать), еще что-то.
20 мар 16, 18:42    [18955881]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
Участник_колективного_труда_КТО)
Guest
Коллективный труд)

Для твоего тесткейса запрос выдаёт все партии побывавших в москве максимум 2 дня:

create index test_ind1 on test(tos,date1,id_partia_towara);
create index test_ind2 on test(froms,date1,id_partia_towara);



select a.id_partia_towara, a.date1 moscow_comein, b.date1 moscow_comeout_to_region, trunc(b.date1-a.date1) happy_days_in_moscow
--count(*)
from test a,test b 
where a.id_partia_towara=B.ID_PARTIA_TOWARA
    and a.tos='Moscow' and b.froms='Moscow' 
    and b.date1>=a.date1
    and (b.date1-a.date1) between 0 and 2
order by a.id_partia_towara;
21 мар 16, 18:18    [18960395]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ускорит выборку данных  [new]
Участник_колективного_труда_КТО)
Guest
так же надо в таблицу городов добавить тип города - столица (москва), регион, буржуйский, буржийский_вражеский(стамбул)
21 мар 16, 18:20    [18960407]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить