Оптимизация SQL запроса с GROUP BY и подзапросом

Интересует, есть ли способы оптимизировать такой запрос в MySQL. Цель: возвратить список отсортированных товаров по популярности, при этом оставить только те товары, которые есть в наличии в конкретных складах и которые имеют цену.

Таблица Описание Поля
products Таблица с главной информацией о товаре
products_prices Таблица с ценами товаров - product_id
- organization_id
- price
То есть у товара может быть несколько цен
product_popularity Таблица, которая хранит информацию об очках популярности - product_id (primary key)
- total
warehouses_products_amount Таблица, которая хранит информацию о кол-ве товаров на складах - product_id
- warehouse_id
- amount
Primary key: product_id+warehouse_id

Запрос:

SELECT products.product_id
     , popularity.total as popularity
     , min(prices.price) 
FROM products    
LEFT JOIN product_popularity as popularity ON 
    popularity.product_id = products.product_id 
LEFT JOIN product_prices as prices ON 
    prices.product_id = products.product_id    
WHERE 
    popularity.total >= 1 
    AND products.status IN ('A') 
    AND prices.organization_id IN (10129, 25195) 
    AND
       (select 1 
        from warehouses_products_amount 
        where product_id=products.product_id 
           and warehouse_id IN('32', '33', '34') 
           and amount>0 limit 1
       ) = 1
GROUP BY products.product_id  
ORDER BY popularity.total desc, products.product_id ASC  
LIMIT 0, 6

Запрос работает моментально (в 10 раз быстрее), если сделать что-то из этого:

  • Убрать GROUP BY products.product_id ИЛИ
  • Убрать ORDER BY popularity.total desc ИЛИ
  • Убрать подзапрос в условии

К сожалению, explain в mysql не дал мне понять, что происходит иначе когда меняешь запрос. Я попробовал вместо подзапроса о наличии товара сделать left join - стало еще хуже. Group by - если убрать, то будут дублирующие товары, т.к. в prices несколько строк соответствуют одному товару. + Мне нужно получить минимальную стоимость этого товара.
Возможно, есть способы избавится от group by, но тогда в других подобных запросах придётся также искать подход для избавления от group by.

Мне интересно, почему этот подзапрос плохо работает вместе с group by / order by popularity . Может быть есть способы как-то сделать иначе ? Или же единственное, что можно сделать это избавится от group by? Если да, то как в такой ситуации лучше от него избавится?

UPD. Explain введите сюда описание изображения

UPD. SQL структура таблиц.

CREATE TABLE `warehouses_products_amount` (
  `warehouse_id` mediumint(8) UNSIGNED NOT NULL,
  `product_id` mediumint(8) UNSIGNED NOT NULL,
  `amount` decimal(8,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `warehouses_products_amount`
  ADD PRIMARY KEY (`product_id`,`warehouse_id`),
  ADD KEY `product_id` (`product_id`);

CREATE TABLE `products` (
  `product_id` mediumint(8) UNSIGNED NOT NULL,
  `product_code` varchar(64) NOT NULL DEFAULT '',
  `product_type` char(1) NOT NULL DEFAULT 'P',
  `status` char(1) NOT NULL DEFAULT 'A',
  
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `products`
  ADD PRIMARY KEY (`product_id`),
  ADD KEY `status` (`status`);
ALTER TABLE `products`
    MODIFY `product_id` mediumint(8) UNSIGNED NOT NULL AUTO_INCREMENT;

CREATE TABLE `product_popularity` (
  `product_id` mediumint(8) UNSIGNED NOT NULL DEFAULT 0,
  `viewed` int(11) NOT NULL DEFAULT 0,
  `added` int(11) NOT NULL DEFAULT 0,
  `deleted` int(11) NOT NULL DEFAULT 0,
  `bought` int(11) NOT NULL DEFAULT 0,
  `total` int(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


ALTER TABLE `product_popularity`
  ADD PRIMARY KEY (`product_id`),
  ADD KEY `total` (`product_id`,`total`);

CREATE TABLE `product_prices` (
`product_id` mediumint(8) UNSIGNED NOT NULL DEFAULT 0,
`price` decimal(12,2) NOT NULL DEFAULT 0.00,
`percentage_discount` int(2) UNSIGNED NOT NULL DEFAULT 0,
`lower_limit` mediumint(8) UNSIGNED NOT NULL DEFAULT 0,
`usergroup_id` mediumint(8) UNSIGNED NOT NULL DEFAULT 0,
`organization_id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `product_prices`
ADD UNIQUE KEY `usergroup` (`product_id`,`usergroup_id`,`lower_limit`,`organization_id`) USING BTREE,
ADD KEY `product_id` (`product_id`),
ADD KEY `lower_limit` (`lower_limit`),
ADD KEY `usergroup_id` (`usergroup_id`,`product_id`),
ADD KEY `organization_id` (`organization_id`);

Ответы (0 шт):