powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Быстрое соединение только одной детали к мастеру
7 сообщений из 7, страница 1 из 1
Быстрое соединение только одной детали к мастеру
    #38772081
X_ginger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Firebird 2.5, Windows 7
Есть 2 таблицы - дел и документов. Связь 1 ко многим. Ключ составной по 2 целым полям. В первой 200 тыс записей, во второй почти 2 млн. Нужно создать запрос, где к каждому делу будет привязан один ЛЮБОЙ документ - цимус в том, что нужно видеть, что документы есть, а какие - можно посмотреть в детальной таблице (по доп.запросу).
Основная проблема - в скорости. Какой наиболее быстрый путь тут может быть?
Таблицы(полей там масса, оставлены только те, что участвуют в запросе)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SET SQL DIALECT 3;

CREATE TABLE CAUSE (
    DBID                         INTEGER NOT NULL
    ID                           INTEGER NOT NULL
    NUMBER                       VARCHAR(50),
);

ALTER TABLE CAUSE ADD CONSTRAINT PK_CAUSE PRIMARY KEY (DBID, ID);


CREATE TABLE DOCUMENT (
    DBID                          INTEGER NOT NULL,
    ID                            INTEGER NOT NULL,
    CAUSE_DBID                    INTEGER,
    CAUSE_ID                      INTEGER,
    AUTHOR                        VARCHAR(50),
    ISDELETED                     INTEGER
);

ALTER TABLE DOCUMENT ADD CONSTRAINT PK_DOCUMENT PRIMARY KEY (DBID, ID);

ALTER TABLE DOCUMENT ADD CONSTRAINT FK_DOCUMENT1 FOREIGN KEY (CAUSE_DBID, CAUSE_ID) REFERENCES CAUSE (DBID, ID) ON DELETE CASCADE;


Данные
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
INSERT INTO CAUSE (DBID, ID, NUMBER) VALUES (401, 204922, '1*ё*3*11');
INSERT INTO CAUSE (DBID, ID, NUMBER) VALUES (439, 520484, '4*270*11');
INSERT INTO CAUSE (DBID, ID, NUMBER) VALUES (428, 677374, '194*2210*13*л');

INSERT INTO DOCUMENT (DBID, ID, CAUSE_DBID, CAUSE_ID, DOCNO, AUTHOR, ISDELETED) VALUES (428, 706342, 428, 677374, 'А55', 'Петров', NULL);
INSERT INTO DOCUMENT (DBID, ID, CAUSE_DBID, CAUSE_ID, DOCNO, AUTHOR, ISDELETED) VALUES (428, 706343, 428, 677374, 'У4', 'Иванов', 1);
INSERT INTO DOCUMENT (DBID, ID, CAUSE_DBID, CAUSE_ID, DOCNO, AUTHOR, ISDELETED) VALUES (428, 706348, 428, 677374, 'р7', 'Сидоров', NULL);
INSERT INTO DOCUMENT (DBID, ID, CAUSE_DBID, CAUSE_ID, DOCNO, AUTHOR, ISDELETED) VALUES (401, 204916, 401, 204922, '455', 'Иванов', NULL);
INSERT INTO DOCUMENT (DBID, ID, CAUSE_DBID, CAUSE_ID, DOCNO, AUTHOR, ISDELETED) VALUES (401, 204933, 401, 204922, '456', 'Сидоров', NULL);
INSERT INTO DOCUMENT (DBID, ID, CAUSE_DBID, CAUSE_ID, DOCNO, AUTHOR, ISDELETED) VALUES (401, 204935, 401, 204922, '457', 'Иванов', 1);
INSERT INTO DOCUMENT (DBID, ID, CAUSE_DBID, CAUSE_ID, DOCNO, AUTHOR, ISDELETED) VALUES (401, 204938, 401, 204922, '458', 'Петров', NULL);



Хочу получить так
Код: plaintext
NUMBERDOCNOAUTHORCAUSE_IDISDELETED1*ё*3*11455Иванов204922 4*270*11194*2210*13*лА55Петров677374Запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select
t1.NUMBER,
t2.DOCNO,
t2.AUTHOR,
t2.CAUSE_ID,
t2.ISDELETED
from CAUSE t1
  left join DOCUMENT t2 on (t1.DBID=t2.CAUSE_DBID and t1.ID=t2.CAUSE_ID and
     t2.ID=(select min(t.ID) from DOCUMENT t where t.CAUSE_ID=t1.ID and t.ISDELETED is null))
where (t2.ISDELETED is null)


План
План
PLAN (T NATURAL)
PLAN JOIN (T1 NATURAL, T2 INDEX (FK_T_DOCUMENT1))

------ Информация о производительности ------
Время подготовки запроса = 0ms
Время выполнения запроса = 51m 13s 95ms
Среднее время на получение одной записи = 99 132,10 ms
Current memory = 88 393 832
Max memory = 88 732 984
Memory buffers = 10 000
Reads from disk to cache = 110 721 546
Writes from cache to disk = 0
Чтений из кэша = -183 366

Можно быстрее?
...
Рейтинг: 0 / 0
Быстрое соединение только одной детали к мастеру
    #38772095
pastor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X_ginger,

selectable EXECUTE BLOCK
...
Рейтинг: 0 / 0
Быстрое соединение только одной детали к мастеру
    #38772099
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X_ginger,
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select x.number, cast(left(x.doc_info, 18) as int) as docno, substring(x.doc_info from 19) as author
from(
  select 
       t1.NUMBER
      ,(select first 1 lpad(t2.docno, 18, ' ') ||  t2.author as doc_info
        from document t2
        where t1.DBID=t2.CAUSE_DBID and t1.ID=t2.CAUSE_ID and t2.isDeleted is null
        order by t2.CAUSE_DBID,t2.CAUSE_ID -- хотя порядок и не важен - не убирать!
       ) 
  from CAUSE t1
) x
...
Рейтинг: 0 / 0
Быстрое соединение только одной детали к мастеру
    #38772102
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X_gingerцимус в том, что нужно видеть, что документы есть
Для этого не надо выбирать записи:
Код: sql
1.
2.
3.
4.
5.
select
t1.NUMBER,
case when exists(select * from DOCUMENT t2 where t1.DBID=t2.CAUSE_DBID and t1.ID=t2.CAUSE_ID and t2.ISDELETED is null)
     then 'Есть документы' ELSE 'Нет документов' END
from CAUSE t1
...
Рейтинг: 0 / 0
Быстрое соединение только одной детали к мастеру
    #38772955
X_ginger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Получилось вот так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select
  t1.NUMBER,
  t2.DOCNO,
  t2.AUTHOR,
  t2.CAUSE_ID,
  t2.ISDELETED
from CAUSE t1
  left join(
    select
      t1.DBID as CAUSE_DBID,
      t1.ID as CAUSE_ID,
      min(t2.DBID) as DBID,
      min(t2.ID) as ID
    from CAUSE t1
      join DOCUMENT t2 on (t1.DBID=t2.CAUSE_DBID and t1.ID=t2.CAUSE_ID) and (t2.ISDELETED is null)
    group by t1.DBID, t1.ID
  ) t on (t1.DBID = t.CAUSE_DBID and t1.ID = t.CAUSE_ID)
  left join DOCUMENT t2 on (t.DBID = t2.DBID and t.ID = t2.ID)
where (t2.ISDELETED is null)


План
PLAN JOIN (JOIN (T1 NATURAL, JOIN (T T1 ORDER FK_DOCUMENT1 INDEX (PK_CAUSE), T T2 INDEX (FK_DOCUMENT1))), T2 INDEX (PK_DOCUMENT))

------ Информация о производительности ------
Время подготовки запроса = 15ms
Время выполнения запроса = 0ms
Среднее время на получение одной записи = 0,00 ms
Current memory = 91 168 536
Max memory = 100 176 760
Memory buffers = 10 000
Reads from disk to cache = 384
Writes from cache to disk = 0
Чтений из кэша = 6 594

Данные те же...
Однако странно - сложнее запрос, длиннее план, но быстрее очень
...
Рейтинг: 0 / 0
Быстрое соединение только одной детали к мастеру
    #38773035
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X_gingerОднако странно - сложнее запрос, длиннее план, но быстрее очень
Мой запрос был бы ещё быстрее и с очень коротким планом. Ты его пробовал вообще?
...
Рейтинг: 0 / 0
Быстрое соединение только одной детали к мастеру
    #38773119
X_ginger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry SibiryakovX_gingerОднако странно - сложнее запрос, длиннее план, но быстрее очень
Мой запрос был бы ещё быстрее и с очень коротким планом. Ты его пробовал вообще?
:) Он конечно быстрее, но... Требование такое - должен быть указан документ, а не его наличие. С exists собственно начали, но заказчику не нра
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Быстрое соединение только одной детали к мастеру
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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