Ответы пользователя по тегу SQL
  • Что не правильно в запросе PostgreSQL?

    @hell
    "В его личном деле было написано - ОСОБЫЕ ПРИМЕТЫ - все" (Dellamorte Dellamore)
    1) Мне кажется, что вам стоит серьезно переработать структуру БД
    2) Перефразируем ваш запрос:
    SELECT *
    FROM products p
    WHERE p.id IN
         (SELECT DISTINCT pc.product_id
          FROM product_characteristic pc
          WHERE pc.product_id = p.id
            AND pc.characteristic_id= ANY   (2,     19,        20)
            AND pc.selected_option_id=ANY (129,   2001569,   2001570, 2001571)
         )

    Или, "совсем по русски"
    SELECT *
    FROM products p
    WHERE p.id IN
         (SELECT DISTINCT pc.product_id
          FROM product_characteristic pc
          WHERE pc.product_id = p.id
            AND (pc.characteristic_id =2 OR  pc.characteristic_id =19 or pc.characteristic_id =20)
            AND (pc.selected_option=129 OR pc.selected_option=2001569 OR pc.selected_option=2001570 or pc.selected_option=2001571)
         )


    То есть вместо пересечения характеристик, вы выбираете их объединение
    Ну и, поскольку подзапрос вообще говоря самостоятелен, и независим от внешнего запроса, я не очень понимаю, что у вас в нем делает p.id и как оно вообще будет работать.
    3) Если попробовать написать то, что вы хотели, получится примерно следующее
    SELECT *
    FROM products p
    WHERE p.id IN
         (SELECT pc.product_id
          FROM product_characteristic pc,  product_characteristic pc1,product_characteristic pc2,  
          WHERE pc.product_id=pc1.product_id and pc.product_id=pc2.product_id
            AND pc.characteristic=2 AND pc.selected_option_id=129
            AND pc1.characteristic=19  AND pc1.selected_option_id=2001569
            AND pc2.characteristic=20  AND pc2.selected_option_id in  (2001570, 2001571)
         )

    Во-первых - убираем DISTINCT из подзапроса - он даст нам перечень product_id, и даже если они будут повторяться, основной запрос выберет только уникальные строки

    Во вторых - добавляем еще два псевдонима к таблице product_characteristic
    для каждого псевдонима ставим свое условие по id характеристики и id выбранной опции

    Ну и сообщаем, что искомый product_id для всех таблиц product_characteristic у вас одинаковый.

    Если у вас selected_option_id уникален для каждой опции, можно исключить из запроса поле selected_option_id
    тогда получится примерно так:
    SELECT *
    FROM products p
    WHERE p.id IN
         (SELECT pc.product_id
          FROM product_characteristic pc,  product_characteristic pc1,product_characteristic pc2,  
          WHERE pc.product_id=pc1.product_id and  pc.product_id=pc2.product_id
            AND pc.selected_option_id=129
            AND pc1.selected_option_id=2001569
            AND pc2.selected_option_id in  (2001570, 2001571)
         )
    Ответ написан
    5 комментариев
  • Как составить SQL запрос?

    @hell
    Попробуйте так:
    select b.* from b, a where a.id in (1,2,3,4,5) and position (a.short_name in b.full_name)>0;

    (за скорость не ручаюсь, ну и скорее всего придется приглядываться к результатам
    Ответ написан
    Комментировать
  • Как оптимизировать производительность большой базы в postgresql?

    @hell
    Собственно, вам нужно поднять значение shared_buffers до величины, чтобы в них влезала ваша максимальная выборка ( общий объем всех таблиц самого большого джойна), установить work_mem так, чтобы все сортировки оказывались в оперативной памяти (смотрится explain analyzeом), а потом (или, скорее - в процессе) заставить вашу машину со всем этим работать, донастроив ядро.
    Ответ написан
    1 комментарий
  • Как оптимизировать производительность большой базы в postgresql?

    @hell
    Теоретически (да и практически, чаще всего), PostgreSQL умный. То есть, весьма велика вероятность, что вам хватит "вдумчивого тюнинга". Правда, тюнинговать придется не только БД, но и операционку (в случае Linux лопатится примерно четверть доступных sysctl).
    Монитровать оперативку скорее всего просто не нужно - как я уже писал, PostgreSQL умный и обычно справляется сам (разумеется с правильными настройками).
    Делить аппаратные ресурсы в вашем случае тоже смысла особого не имеет - PostgreSQL очень хорошо параллелится.
    Возможно, вам еще стоит посмотреть в сторону pgbouncer - в режиме transaction и с постоянными соединениями он держит СУБД в "разогретом" состоянии, а это, насколько я понимаю, в данном случае и будет являться потенциальным бутылочным горлышком.
    Ответ написан
    3 комментария