Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Вопрос по оптимизации запроса / 12 сообщений из 12, страница 1 из 1
30.10.2017, 02:36
    #39544115
MBlack
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
Здорова товарищи.
Хочу сделать запрос следующего характера (хочу узнать какое количество и сколько продано каждого товара, на какой то период, или там в каком филиале сколько продано)

Есть следующие таблицы
Код: sql
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.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
CREATE TABLE PRODUCTS (
    ID           DINT_NOT_NULL NOT NULL /* DINT_NOT_NULL = INTEGER NOT NULL */,
    ID_FAC       DINT_NULL DEFAULT 0 /* DINT_NULL = INTEGER */,
    ID_CAT       DINT_NOT_NULL /* DINT_NOT_NULL = INTEGER NOT NULL */,
    PRODUCTNAME  DVCHAR_AVERAGE /* DVCHAR_AVERAGE = VARCHAR(150) */,
    UNITPRICE    DMONEY /* DMONEY = DECIMAL(15,2) */,
    DESCPROD     BLOB SUB_TYPE 1 SEGMENT SIZE 80,
    UNITDIMEN    VARCHAR(5),
    QUANTSG      DINT_NULL /* DINT_NULL = INTEGER */,
    AKCIYA       SMALLINT DEFAULT 2
);


CREATE TABLE ORDERSDETAILS (
    ID                 DINT_NOT_NULL NOT NULL /* DINT_NOT_NULL = INTEGER NOT NULL */,
    ORDID              DINT_NOT_NULL /* DINT_NOT_NULL = INTEGER NOT NULL */,
    PRODUCTID          DINT_NOT_NULL /* DINT_NOT_NULL = INTEGER NOT NULL */,
    QUANTITY           SMALLINT,
    UNITPRICE          DMONEY /* DMONEY = DECIMAL(15,2) */,
    DISCOUNT           DINT_NULL /* DINT_NULL = INTEGER */,
    TAKCIYA            SMALLINT DEFAULT 0,
    MOREINFOITEM       DVARCHAR /* DVARCHAR = VARCHAR(250) */,
    CURRMINFOMOREITEM  DMONEY DEFAULT 0 /* DMONEY = DECIMAL(15,2) */,
    TPRODUCT           SMALLINT DEFAULT 1,
    RESTITEM           SMALLINT DEFAULT 0
);

CREATE TABLE ORDERS (
    ID            DINT_NOT_NULL NOT NULL /* DINT_NOT_NULL = INTEGER NOT NULL */,
    ORDERNUM      VARCHAR(50),
    ORDCOUNT      SMALLINT DEFAULT 0,
    CUSTOMERID    DINT_NOT_NULL /* DINT_NOT_NULL = INTEGER NOT NULL */,
    OPERATORID    DINT_NOT_NULL /* DINT_NOT_NULL = INTEGER NOT NULL */,
    ORDERDATE     DDATE /* DDATE = DATE */,
    ORDERTIME     DTIME /* DTIME = TIME */,
    DELIVERYADR   VARCHAR(250),
    ITEMKCH       DINT_NULL /* DINT_NULL = INTEGER */,
    PKGONE        SMALLINT,
    ORDERSTATUS   SMALLINT DEFAULT 1,
    CURRDELAVERY  DMONEY DEFAULT 0 /* DMONEY = DECIMAL(15,2) */,
    ODISCONT      DMONEY DEFAULT 0 /* DMONEY = DECIMAL(15,2) */,
    DESCORDER     DVARCHAR /* DVARCHAR = VARCHAR(1024) */,
    MOREINFORDER  DVARCHAR /* DVARCHAR = VARCHAR(1024) */,
    APRINT        SMALLINT DEFAULT 0,
    APRKITCH      SMALLINT DEFAULT 0
);

CREATE INDEX ORDERS_IDX1 ON ORDERS (CUSTOMERID);
CREATE INDEX ORDERS_IDX2 ON ORDERS (ORDERSTATUS);
CREATE INDEX ORDERS_IDX3 ON ORDERS (ORDERNUM);
CREATE INDEX ORDERS_IDX4 ON ORDERS (ORDERDATE);
CREATE INDEX ORDERS_IDX5 ON ORDERS (ORDERTIME);



Делаю вот такой запрос

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
with tm as (
                  select od.productid,
                            sum(od.quantity) as qty , sum(od.quantity*od.unitprice) as proiz
                             from ordersdetails od inner join orders o on o.id = od.ordid
                 -- where o.orderdate between '01.02.2017' and '31.12.2017'
                 --       and o.itemkch = 0
                  group by od.productid

) select
     t.productid,
     p.productname,
     t.qty as qty,
     t.proiz as sm
  from tm t left join products p on t.productid = p.id



Но выполняется он где 1s 150ms или 992ms
Ну то ест долго.

в таблице записей около 200 тыс.

Не подскажите как мне оптимизировать этот запрос, чтоб он выполнялся быстрее

Заранее спасибо!!!
...
Рейтинг: 0 / 0
30.10.2017, 02:52
    #39544116
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
Код: sql
1.
2.
3.
4.
5.
     select od.productid,
                           sum(od.quantity) as qty , 
                           sum(od.quantity*od.unitprice) as proiz
                        from ordersdetails od inner join orders o on o.id = od.ordid
                  group by od.productid



Что-то я не могу понять - зачем здесь таблица orders
Связь есть, но никакие данные оттуда не берутся.
...
Рейтинг: 0 / 0
30.10.2017, 03:01
    #39544117
MBlack
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
982183,

Мне нужно из таблицы вытаскивать, вытаскивать, данные за определенный период то есть даты или время,
то есть нужно допустим я задам временной интервал , и мне должен запрос вернуть сколько товара и продано за этот период
...
Рейтинг: 0 / 0
30.10.2017, 03:14
    #39544119
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
Увидел в комментах.
Но проблему не понимаю.
Время вполне комфортное.

Я решаю подобные мелкие задачи не запросами-отчетами,
а готовлю набор данных в EXEL, а на местах уже в сводных таблицах пользователи группируют их по своему желанию.
800т записей обрабатываются вполне комфортно.
...
Рейтинг: 0 / 0
30.10.2017, 10:53
    #39544236
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
MBlack,

Приведённое время с учётом фильтра по дате? Надеюсь, индекс по дате есть? Покажи план выполнения. Я бы ещё left join на inner join поменял. Иногда помогает.
...
Рейтинг: 0 / 0
30.10.2017, 12:18
    #39544316
MBlack
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
По дате индекс есть
CREATE INDEX ORDERS_IDX4 ON ORDERS (ORDERDATE);
...
Рейтинг: 0 / 0
30.10.2017, 12:21
    #39544319
MBlack
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
Вот план

План
PLAN JOIN (SORT (JOIN (T O INDEX (ORDERS_IDX4), T OD INDEX (FK_ORDERSDETAILS_2), T P INDEX (PK_PRODUCTS))), P INDEX (PK_PRODUCTS))

------ Информация о производительности ------
Время подготовки запроса = 47ms
Время выполнения запроса = 1s 60ms
Среднее время на получение одной записи = 43,68 ms
Current memory = 38 449 640
Max memory = 101 708 832
Memory buffers = 2 048
Reads from disk to cache = 667
Writes from cache to disk = 4
Fetches from cache = 0
...
Рейтинг: 0 / 0
30.10.2017, 12:27
    #39544326
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
MBlack,

ну и чём тебе время не нравится. 1 секунда это вполне нормально, вот если бы 1 минута...
...
Рейтинг: 0 / 0
30.10.2017, 12:54
    #39544353
MBlack
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
понятно
...
Рейтинг: 0 / 0
30.10.2017, 13:06
    #39544370
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
MBlackReads from disk to cache = 667
Writes from cache to disk = 4
Fetches from cache = 0

Это первый запрос к холодной базе, он упирается в скорость диска. На продакшене либо ставь
более быстрые диски, либо не давай базе остыть.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
30.10.2017, 13:48
    #39544422
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
Dimitry SibiryakovЭто первый запрос к холодной базе

лиюо маленькие кэши и таблицы вытеснены были другими запросами
...
Рейтинг: 0 / 0
30.10.2017, 14:48
    #39544497
Ivan_Pisarevsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по оптимизации запроса
предварительно агрегировать данные, например, по дням. В онлайне придется лопатить меньше.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Вопрос по оптимизации запроса / 12 сообщений из 12, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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