|   |   | 
| 
 | Как ускорить запрос в 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 помогает     | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |