За последние 24 часа нас посетили 16578 программистов и 1643 робота. Сейчас ищут 1260 программистов ...

Помогите разобраться с медленным запросом

Тема в разделе "PostgreSQL", создана пользователем nekit44, 20 дек 2022.

Метки:
  1. nekit44

    nekit44 Активный пользователь

    С нами с:
    27 дек 2015
    Сообщения:
    39
    Симпатии:
    2
    Всем привет, подскажите новичку

    Есть такой запрос:

    Код (Text):
    1. select
    2. item_id,
    3. ( POW((l0 - 0.101), 2) + POW((l1 - 0.101), 2) + POW((l2 - 0.101), 2) + POW((l3 - 0.101), 2) + POW((l4 - 0.101), 2) + POW((l5 - 0.101), 2) ) as similarity,
    4. p.filename as filename,
    5.   p.path as path
    6.  
    7. from item_descriptions join item p on p.id = item_descriptions.item_id where item_id <> 1 and user_id is null order by similarity asc limit 100
    математика считается и присваивается псевдониму similarity в последствии по этому полю производится сортировка, на 1 миллионе записей обработка 1.5 минуты, что "долго" так как база еще продолжает расти, будет еще медленней

    Всю голову себе сломал, как ускорить
    1) сортировка по float наверно не самое быстрое, менял на int не много быстрей но не значительно
    2) даже звучит бредово, индекс же не навесить на псевдоним

    Если убрать order by similarity asc отрабатывает за доли секунды, но мне кажется прирост скорости из за того что указан limit

    Был бы рад любой помощи/совету
     
  2. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    @nekit44, быть может, выгоднее вычисляемые значения хранить в связанной таблице, чтобы не выполнять много-много возведений в степень?
    То есть, при создании/обновлении записи с полями l1, l2 и т.д. - сразу вычислять и сохранять подобные pow(lx-0.101, 2) значения и уже по ним сортировать...
     
  3. nekit44

    nekit44 Активный пользователь

    С нами с:
    27 дек 2015
    Сообщения:
    39
    Симпатии:
    2
    рад бы хранить это в отдельных столбцах но для каждой строки нужна математика, если сохранить в поле то нарушается бизнес логика
    если сильно утрировать то будет расчет только одной строки корректный а остальные нет, получается на каждую такую строку в геометрической прогрессии нужно хранить каждый расчет каждой строки
     
  4. nekit44

    nekit44 Активный пользователь

    С нами с:
    27 дек 2015
    Сообщения:
    39
    Симпатии:
    2
    Может кому пригодится

    решил я проблему

    Код (Text):
    1.  
    2. with withTable as (
    3. select
    4. item_id,
    5. ( POW((l0 - 0.101), 2) + POW((l1 - 0.101), 2) + POW((l2 - 0.101), 2) + POW((l3 - 0.101), 2) + POW((l4 - 0.101), 2) + POW((l5 - 0.101), 2) ) as similarity from table_name
    6. )
    7. select item_id, similarity from withTable
    8. where similarity < 0.3
    9. limit 20
    запрос отрабатывает за 1 секунду, что до этого занимало 1.5 минуты