Новичок
Покинул форум
Сообщений всего: 3
Дата рег-ции: Апр. 2014
Помог: 0 раз(а)
|
Приветствую. Есть вот такой запрос:
CODE ( SQL):
скопировать код в буфер обмена
SELECT `catalog`.`id` FROM `test_ru_catalog` AS `catalog` JOIN `test_ru_catalog_group` AS `gr4316` ON `gr4316`.`parent` = `catalog`.`id` JOIN `test_ru_catalog_group` AS `gr4301` ON `gr4301`.`parent` = `catalog`.`id` JOIN `test_ru_catalog_group` AS `gr4311` ON `gr4311`.`parent` = `catalog`.`id` JOIN `test_ru_catalog_group` AS `gr4319` ON `gr4319`.`parent` = `catalog`.`id` JOIN `test_ru_catalog_group` AS `gr4330` ON `gr4330`.`parent` = `catalog`.`id` JOIN `test_ru_catalog_group` AS `gr4323` ON `gr4323`.`parent` = `catalog`.`id` JOIN `test_ru_catalog_group` AS `gr4327` ON `gr4327`.`parent` = `catalog`.`id` JOIN `test_ru_catalog_group` AS `gr21663` ON `gr21663`.`parent` = `catalog`.`id` WHERE `catalog`.`check_active` = 1 AND `catalog`.`check2_archive` = 0 AND `gr4316`.`text_name` IN (4317,4318) AND `gr4301`.`text_name` IN (4302,4307) AND `gr4311`.`text_name` IN (4312) AND `gr4319`.`text_name` IN (4321) AND `gr4330`.`text_name` IN (4332) AND `gr4323`.`text_name` IN (4324) AND `gr4327`.`text_name` IN (4328) AND `gr21663`.`text_name` IN (21664) ORDER BY `catalog`.`ord` DESC LIMIT 0,16;
Это некий фильтр товаров, запрос строится динамически, на основе выбранных юзером значений фильтра. Каждый JOIN здесь - это группа фильтра (производитель, цвет и т.п.), естественно, чем больше выбрано групп, тем больше будет и JOIN.
Структура таблиц (упрощенная):
Спойлер (Отобразить)
CODE ( SQL):
скопировать код в буфер обмена
CREATE TABLE `test_ru_catalog` ( `id` int(11) UNSIGNED NOT NULL, `parent` int(11) UNSIGNED NOT NULL DEFAULT '0', `ord` int(11) UNSIGNED NOT NULL DEFAULT '0', `check_active` tinyint(1) UNSIGNED NOT NULL DEFAULT '1', `name` varchar(255) NOT NULL DEFAULT '', `pselect_brand_6` int(11) NOT NULL, `check2_new` tinyint(1) DEFAULT '0', `check2_archive` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`), KEY `parent` (`parent`), KEY `check2_new` (`check2_new`), KEY `check2_archive` (`check2_archive`), KEY `check_active` (`check_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `test_ru_catalog_group` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `parent` int(11) UNSIGNED NOT NULL DEFAULT '0', `ord` int(11) UNSIGNED NOT NULL DEFAULT '0', `check_active` tinyint(1) UNSIGNED NOT NULL DEFAULT '1', `check_end` tinyint(1) UNSIGNED NOT NULL DEFAULT '0', `text_name` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `parent` (`parent`,`text_name`) USING BTREE, KEY `text_name` (`text_name`) ) ENGINE=InnoDB AUTO_INCREMENT=29578 DEFAULT CHARSET=utf8;
EXPLAIN запроса:
Спойлер (Отобразить)
+----+-------------+---------+--------+-------------------------------------+-----------+---------+-------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+--------+-------------------------------------+-----------+---------+-------------------------+------+----------------------------------------------+
| 1 | SIMPLE | gr4301 | range | parent,text_name | text_name | 5 | NULL | 135 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | gr4330 | ref | parent,text_name | parent | 9 | tmp.gr4301.parent,const | 11 | Using where; Using index |
| 1 | SIMPLE | gr4311 | ref | parent,text_name | parent | 9 | tmp.gr4330.parent,const | 11 | Using where; Using index |
| 1 | SIMPLE | gr4319 | ref | parent,text_name | parent | 9 | tmp.gr4330.parent,const | 11 | Using where; Using index |
| 1 | SIMPLE | gr4323 | ref | parent,text_name | parent | 9 | tmp.gr4301.parent,const | 11 | Using where; Using index |
| 1 | SIMPLE | gr4327 | ref | parent,text_name | parent | 9 | tmp.gr4323.parent,const | 11 | Using where; Using index |
| 1 | SIMPLE | gr21663 | ref | parent,text_name | parent | 9 | tmp.gr4327.parent,const | 11 | Using where; Using index |
| 1 | SIMPLE | gr4316 | ref | parent,text_name | parent | 4 | tmp.gr4301.parent | 150 | Using where; Using index |
| 1 | SIMPLE | catalog | eq_ref | PRIMARY,check2_archive,check_active | PRIMARY | 4 | tmp.gr4301.parent | 1 | Using where |
+----+-------------+---------+--------+-------------------------------------+-----------+---------+-------------------------+------+----------------------------------------------+
9 rows in set
С увеличением количества JOIN время выполнения запроса выходит весьма значительное (от 40 сек), буду очень благодарен, если подкините идею, как это все можно оптимизировать. Этот чудесный запрос достался по наследству.
Готов так же рассмотреть изменение структуры БД.
Спасибо.(Отредактировано автором: 03 Февраля, 2015 - 17:14:24)
|