Добрый день, имеется 4 таблицы
Таблица, где хранится основная инфа о товарах.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE TABLE `oc_product` (
`product_id` int NOT NULL AUTO_INCREMENT,
`model` varchar(64) NOT NULL,
`quantity` int NOT NULL DEFAULT '0',
`image` varchar(255) DEFAULT NULL,
`manufacturer_id` int NOT NULL,
`price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`date_available` date NOT NULL DEFAULT '1990-09-02',
`inlay` varchar(255) DEFAULT NULL,
`sort_order` int NOT NULL DEFAULT '0',
`status` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`product_id`),
KEY `quantity` (`quantity`),
KEY `status` (`status`),
KEY `image` (`image`),
KEY `manufacturer_id` (`manufacturer_id`),
KEY `price` (`price`),
KEY `model` (`model`)
) ENGINE=InnoDB AUTO_INCREMENT=41298 DEFAULT CHARSET=utf8
Таблица, хранящая акционные цены
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
CREATE TABLE `oc_product_discount` (
`product_discount_id` int NOT NULL AUTO_INCREMENT,
`product_id` int NOT NULL,
`customer_group_id` int NOT NULL,
`quantity` int NOT NULL DEFAULT '0',
`priority` int NOT NULL DEFAULT '1',
`price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`date_start` date NOT NULL DEFAULT '1990-10-10',
`date_end` date NOT NULL DEFAULT '2025-10-10',
PRIMARY KEY (`product_discount_id`),
KEY `product_id` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Таблица, хранящая информацию о скидках
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
CREATE TABLE `oc_product_special` (
`product_special_id` int NOT NULL AUTO_INCREMENT,
`product_id` int NOT NULL,
`customer_group_id` int NOT NULL,
`priority` int NOT NULL DEFAULT '1',
`price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`date_start` date NOT NULL DEFAULT '1990-10-10',
`date_end` date NOT NULL DEFAULT '2025-10-10',
PRIMARY KEY (`product_special_id`),
KEY `product_id` (`product_id`),
KEY `special_price` (`price`)
) ENGINE=InnoDB AUTO_INCREMENT=15752 DEFAULT CHARSET=utf8
Таблица с атрибутами
1.
2.
3.
4.
5.
6.
7.
CREATE TABLE `oc_product_attribute` (
`product_id` int NOT NULL,
`attribute_id` int NOT NULL,
`language_id` int NOT NULL,
`text` text NOT NULL,
PRIMARY KEY (`product_id`,`attribute_id`,`language_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Есть основной запрос, получающий список товаров, которые группируем по артикулу, но получается так, что Mysql во время Group by отдает product_id с не самой низкой ценой, а задача в том, чтобы получать именно с самой низкой. Средняя скорость выполнения запроса 0.0081 c
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
SELECT
p.model,
p.product_id,
p.price
,
(
SELECT
price
FROM
oc_product_discount pd2
WHERE
pd2.product_id = p.product_id AND pd2.quantity > 0 AND(
(
pd2.date_start = '1990-10-10' OR pd2.date_start < '2021-01-20 06:18:00'
) AND(
pd2.date_end = '1990-10-10' OR pd2.date_end > '2021-01-20 06:18:00'
)
)
ORDER BY
pd2.priority ASC,
pd2.price ASC
LIMIT 1
) AS discount,(
SELECT
price
FROM
oc_product_special ps
WHERE
ps.product_id = p.product_id AND(
(
ps.date_start = '1990-10-10' OR ps.date_start < '2021-01-20 06:18:00'
) AND(
ps.date_end = '1990-10-10' OR ps.date_end > '2021-01-20 06:18:00'
)
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT 1
) AS special
FROM
oc_product AS p
INNER JOIN
oc_product_to_category p2c
ON
(p.product_id = p2c.product_id)
WHERE
p.quantity > 0 AND p.status > 0 AND p.image IS NOT NULL AND p.price BETWEEN -1 AND 1000000 AND p2c.category_id IN (24, 31)
LIMIT 0, 60
План запроса
Первым, что пришло в голову обернуть основной запрос в ещё один, сортируя во вложенном по возрастанию, сделать получилось, но скорость выполнения увеличилась до 0.2342 сек
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
SELECT price, product_id, model FROM
(SELECT
p.model,
p.product_id,
p.price,
(
SELECT
price
FROM
oc_product_discount pd2
WHERE
pd2.product_id = p.product_id AND pd2.quantity > 0 AND(
(
pd2.date_start = '1990-10-10' OR pd2.date_start < '2021-01-20 06:18:00'
) AND(
pd2.date_end = '1990-10-10' OR pd2.date_end > '2021-01-20 06:18:00'
)
)
ORDER BY
pd2.priority ASC,
pd2.price ASC
LIMIT 1
) AS discount,(
SELECT
price
FROM
oc_product_special ps
WHERE
ps.product_id = p.product_id AND(
(
ps.date_start = '1990-10-10' OR ps.date_start < '2021-01-20 06:18:00'
) AND(
ps.date_end = '1990-10-10' OR ps.date_end > '2021-01-20 06:18:00'
)
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT 1
) AS special
FROM
oc_product p
INNER JOIN
oc_product_attribute AS pa1
ON
(p.product_id = pa1.product_id)
WHERE
p.quantity > 0 AND p.status > 0 AND p.image IS NOT NULL AND pa1.attribute_id IN(7, 12, 154) AND p.price BETWEEN -1 AND 1000000 ORDER BY p.price ASC) AS tab
GROUP BY model
LIMIT 0, 60
И перестал работать индекс
План запроса
Пробовали в первоначальной версии запроса отменять сортировку у GROUP BY при помощи ORDER BY NULL, но не помогает.
Пробовали FORCE-ить индекс тоже не помогает.
Может есть какой-то более "легкий" вариант для решения нашей задачи?
Версия Mysql 8.0.22