Имеется 3 таблицы с товаром и его параметрами:
Товары (goods): id, article, num (num - число опций, описанных для текущего артикула)
Параметры (options): id, option
Значения (cross): id, goods_id, options_id, value
Осуществляется поиск артикула товара по набору опций и их значениям, например: Вес=15кг, Цвет=Красный и Упаковка=Пластик. Необходимо выбрать только те товары у которых присутствуют все эти значения одновременно, но при этом нет больше никаких других значений (например Ширина, Длина и т.п.). Ели задается пустой поисковый запрос то система должна вернуть те товары, где нет значения ни для одного параметра.
Сейчас это работает так:
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`='Синий'
));
Где число в
`goods`.`num`='2' подставляется из кода и соответствует числу выражений типа
`options_id`='1' AND `value`='15кг', которые так же генерируются автомотически в нужном количестве.
Проблема заключается в том, что при большом (десятки тысяч и более) количестве товаров и опций запрос начинает притормаживать до нескольких секунд, что хотелось бы исправить, но лучшего не придумаю. Очень желатьельно осуществить поиск в один SQL запрос.
Примеры самих таблиц
Товары:
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, 'Металл');