Answer the question
In order to leave comments, you need to log in
How to optimize SQL query for product selection by parameters?
There are 3 tables with a product and its parameters:
Goods: id, article, num (num - the number of options described for the current article)
Parameters (options): id, option
Values (cross): id, goods_id, options_id, value
The article is searched for by a set of options and their values, for example: Weight=15kg, Color=Red and Packaging=Plastic. It is necessary to select only those products that have all these values at the same time, but there are no other values (for example, Width, Length, etc.). If an empty search query is specified, then the system should return those products where there is no value for any parameter.
Now it works like this:
SELECT `goods`.`article` FROM `goods`
WHERE
`goods`.`num`='2' AND
`goods`.`num`=(SELECT COUNT(*) FROM `cross` WHERE `cross`.`goods_id`=`goods`.`id` AND (
`options_id`='1' AND `value`='15кг'
OR
`options_id`='4' AND `value`='Синий'
));
CREATE TABLE `goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`article` varchar(127) NOT NULL,
`num` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `article` (`article`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Товары' AUTO_INCREMENT=11 ;
INSERT INTO `goods` (`id`, `article`, `num`) VALUES
(1, 'Артикул 1', 1), (2, 'Артикул 2', 1), (3, 'Артикул 3', 1), (4, 'Артикул 4', 1), (5, 'Артикул 5', 1), (6, 'Артикул 6', 2), (7, 'Артикул 7', 2), (8, 'Артикул 8', 3), (9, 'Артикул 9', 3), (10, 'Артикул 10', 4);
CREATE TABLE `options` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`option` varchar(127) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `option` (`option`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Опции' AUTO_INCREMENT=6 ;
INSERT INTO `options` (`id`, `option`) VALUES
(1, 'Вес'), (2, 'Длина'), (3, 'Ширина'), (4, 'Цвет'), (5, 'Упаковка');
CREATE TABLE `cross` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`goods_id` int(11) NOT NULL,
`options_id` int(11) NOT NULL,
`value` varchar(127) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `goods_id` (`goods_id`,`options_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Параметры товара' AUTO_INCREMENT=20 ;
INSERT INTO `cross` (`id`, `goods_id`, `options_id`, `value`) VALUES
(1, 1, 1, '15кг'), (2, 2, 2, '120см'), (3, 3, 3, '50см'), (4, 4, 4, 'Синий'), (5, 5, 5, 'Картон'), (6, 6, 1, '15кг'), (7, 6, 4, 'Синий'), (8, 7, 1, '15кг'), (9, 7, 4, 'Красный'), (10, 8, 1, '15кг'), (11, 8, 4, 'Синий'), (12, 8, 5, 'Картон'), (13, 9, 1, '15кг'), (14, 9, 4, 'Белый'), (15, 9, 5, 'Пластик'), (16, 10, 1, '30кг'), (17, 10, 2, '120см'), (18, 10, 3, '50см'), (19, 10, 5, 'Металл');
Answer the question
In order to leave comments, you need to log in
SELECT `goods`.`article`
FROM `goods`
JOIN `cross` AS `c1` ON `c1`.`goods_id` = `goods`.`id`
AND `c1`.`options_id`='1' AND `c1`.`value`='15кг'
JOIN `cross` AS `c2` ON `c2`.`goods_id` = `goods`.`id`
AND `c2`.`options_id`='4' AND `c2`.`value`='Синий'
Make an INDEX for the fields you are looking for. We also had such problems at work, the request even happened to be processed for 10 seconds. And of course, do everything through 1 request, there should be 1 request, do not use subqueries.
http://ruhighload.com/post/Working+with+indexes+in+MySQL
Can through Join make, instead of subqueries. And I didn’t understand about num, why is it needed?
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question