Какой смысл использовать SELECT DISTINCT для функции getProducts в классе shopProductsCollection.class.php в постраничной навигации и Upselling?

Возникла проблема, что долго(2-3 сек) открываются страницы категорий и страницы товаров, если включен Upselling.

Все запросы на эти страницы запрашивают постоянно все поля товаров(p.*).

Естественно идентичных строк SELECT DISTINCT не найдет.

И как-то не правильно это запрашивать все поля товаров. Это же долго.

ps: в магазине 400-500 тысяч товаров )

и есть категории с листингом под 30-40 тысяч товаров.

Но при таком большом количестве товаров - даже категории и с 1-10 тысячами товаров тоже долго открываются постранично.

Надо все-таки оптимизровать sql-запросы.

Примеры запросов:

SELECT DISTINCT p.*,p.id,(p.count > 0 || p.count IS NULL) AS in_stock
FROM shop_product p
        JOIN shop_category_products cp1
                ON p.id = cp1.product_id
WHERE p.type_id IN (8)
        AND p.status = 1
        AND cp1.category_id IN(732,733,734,735,736,737,738,751)
ORDER BY in_stock DESC, cp1.sort ASC
LIMIT 40620,60

Если убрать DISTINCT - уже 1 секунду экономим )

А выше-указанный запрос надо как-то попробовать разложить на простые. Хотя и не уверен, что поможет существенно...

Вот если запрашивать определенные строки(в зависимости от запроса), а не все - уже лучше стало бы.

3 ответа

  • 1
    Естественно идентичных строк SELECT DISTINCT не найдет.

    очень даже найдет, перед продолжением дисскуссии рекомендую выполнить запрос в phpmyadmin и подивиться результату

    • +1
      Nail Nail 16 октября 2018 16:56 #

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

      Как он найдет - если запрашиваются все поля товаров - *?

      Для этого хотя бы у двух товаров должны будут совпасть все поля.

      Если вы с таким сталкивались - скиньте пример, если не затруднит.

      • +1

        Все дело в join'ах и том что данный запрос - частный случай, а метод универсальный и в select'е может быть все что угодно, например, "select p.name,p.price" без distinct вернет дубли.

        $distinct = $this->joins && !$this->group_by ? 'DISTINCT ' : '';

        • +1
          Nail Nail 16 октября 2018 19:07 #

          может случай и частный - но он формируется для всех страниц пагинаций и категорий, а также для вывод блока Upselling на странице товара.

          Если разработчики захотят - может сделают для этих часто посещаемых страниц более оптимизированные запросы, не используя чисто "p.*".

          ps: пока убрал из getProducts distinct - уже стало намного легче - а вывод товаров в количестве и сортировке не поменялся )

          буду искать дальше.

        • +1

          Товар может быть в нескольких дочерних категориях и у просматриваемой включен режим показа товаров из дочерних. Например

          • +1
            Nail Nail 17 октября 2018 07:07 #

            А не проще было тогда сперва выбрать уникальные в таблице shop_category_products и потом этот результат присоединять? )

            Или еще есть случаи(если вообще были), что есть дубли товаров по 2-3 полям и более в таблице shop_product?

  • 1
    Михаил Ушенин Webasyst 16 октября 2018 18:25 #

    Возможно, часть запросов получится оптимизировать вот так.

  • 1
    km Партнер-разработчик 17 октября 2018 09:27 #

    возьмите сервер нормальный и залейте все оперативкой, бизнес же превыше всего

    • +1
      Nail Nail 17 октября 2018 12:37 #

      мы в курсе )

      не думали что понадобится.

      И тут не в оперативке проблема, а скорее в процессоре.

      Так как база вся вместе с индексами занимает не более 800-900 Мбайт.

      Оперативы на VPS - 2 Гбайт.

      Пока работает на VPS с выделенным ядром XEON(2013-2014 года) 2-3 ГГц.

      На выделенном надо попробовать. Так как все упирается в производительность одного ядра процессора. 

Добавить ответ

Чтобы добавить комментарий, зарегистрируйтесь или войдите