Имя: Пароль:
IT
Админ
Как ускорить запрос в postgres?
0 GANR
 
09.09.24
17:11
Есть запрос, таблицы document и organisation содержат очень много записей. Колонка id в обеих таблицах - первичный ключ, число.

select
    d.*,
    o.*
from
    document as d
        left join organisation as o on
            d.organisationid = o.id
order by
    o.name
limit 10;

Есть индексы - не помогают

create index organisation_id_name_index on organisation(id, name);
create index document_organisationid_index on document(organisationid);

Как ускорить?
1 asady
 
09.09.24
17:16
select
    d.*,
    o.*
from
    organisation as o
        inner join document as d
        on o.id = d.organisationid
order by
    o.name
limit 10;
2 GANR
 
09.09.24
17:19
(1) Хм... Судя по плану индекс хоть и подцепился, но всё равно тормозит запрос ((
3 asady
 
09.09.24
17:23
(2) это все что ты можешь выжать - теперь смотри сам скуль - его настройки
4 H A D G E H O G s
 
09.09.24
18:47
При текущей постановке логики запроса это невозможно.

Всему вина LeftJoin - который "разрешает" правой таблице "organisation" "вольности", ведь в правой таблице может быть несколько записей, выполняющих условие и результат limit будет зависеть от них, ПОЭТОМУ нам нужно сначало полностью соединить 2 таблицы, перебрав их и затем наложить limit. Заменив LeftJoin на InnerJoin мы жестко ограничим правую таблицу и limit 10 сработает - мы выберем 10 записей из левой таблицы и присоединим к ним записи правой таблицы.

Или же.

Если позволяет логика, использовать вот это

select
    subDocument.*,
    o.*
from
    (select top 10 d.* from document as d) as subDocument
        left join organisation as o on
            subDocument.organisationid = o.id
order by
    o.name


Проверялось на ms sql
5 Fram
 
09.09.24
18:57
(0) document видимо огромная таблица?
А если попробовать сначала выбрать 10 организаций с сортировкой по наим, и через IN?
6 Fram
 
09.09.24
18:55
(4) Совсем не годится, ему же по наим организаций надо отсортировать
7 H A D G E H O G s
 
09.09.24
19:03
(6) keyword: "Если позволяет логика"
8 Fram
 
09.09.24
19:06
(7) Сорри за оффтоп, можешь на это глянуть? Опять закрытие месяца в БП 3
9 GANR
 
09.09.24
21:26
(7)  Хорошую скорость получил заменив left join на inner join, а индекс построил в org по 1 полю name.

Остаётся присобачить через union all docs, у которых организация null. Констрейнт у поля организация есть.
12 H A D G E H O G s
 
10.09.24
10:29
(9) Можно так
select top 10
    d.id,
    d.organisationid,
    o.id,
    o.name
from
    document as d
        inner join organisation as o on
            d.organisationid = o.id

union all
select top 10
    d.id,
    d.organisationid,
    null,
    null
from
    document as d
order by
    o.name
13 H A D G E H O G s
 
10.09.24
10:33
(9) Можно так, как посоветовали (5), но нужен индекс
on organisation(NAME,ID);

select top 10
    d.id,
    d.organisationid,
    subOrganisation.id,
    subOrganisation.name
from
    document as d
        left join (select top 10 o.* from organisation as o order by name) as subOrganisation on
            d.organisationid = subOrganisation.id
14 H A D G E H O G s
 
10.09.24
10:33
(8) Нужна выгрузка базы и описание воспроизведения.
15 Tonic54
 
10.09.24
11:22
Индекс по name пробовали строить?
16 GANR
 
11.09.24
11:02
(15) Да, при работе по inner join помогает
Здесь можно обсудить любую тему при этом оставаясь на форуме для 1Сников, который нужен для работы. Ymryn