Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Оптимизация запроса
Форумы портала PHP.SU » » Работа с СУБД » Оптимизация запроса

Страниц (1): [1]
 

1. evgen_dev - 03 Февраля, 2015 - 16:31:22 - перейти к сообщению
Приветствую. Есть вот такой запрос:

CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT `catalog`.`id` FROM `test_ru_catalog` AS `catalog`
  3.  
  4.  JOIN `test_ru_catalog_group` AS `gr4316`  ON `gr4316`.`parent` = `catalog`.`id`
  5.  JOIN `test_ru_catalog_group` AS `gr4301`  ON `gr4301`.`parent` = `catalog`.`id`
  6.  JOIN `test_ru_catalog_group` AS `gr4311`  ON `gr4311`.`parent` = `catalog`.`id`
  7.  JOIN `test_ru_catalog_group` AS `gr4319`  ON `gr4319`.`parent` = `catalog`.`id`
  8.  JOIN `test_ru_catalog_group` AS `gr4330`  ON `gr4330`.`parent` = `catalog`.`id`
  9.  JOIN `test_ru_catalog_group` AS `gr4323`  ON `gr4323`.`parent` = `catalog`.`id`
  10.  JOIN `test_ru_catalog_group` AS `gr4327`  ON `gr4327`.`parent` = `catalog`.`id`
  11.  JOIN `test_ru_catalog_group` AS `gr21663` ON `gr21663`.`parent` = `catalog`.`id`
  12.                                      
  13. WHERE `catalog`.`check_active` = 1 AND `catalog`.`check2_archive` = 0
  14.  
  15.         AND `gr4316`.`text_name` IN (4317,4318)
  16.         AND `gr4301`.`text_name` IN (4302,4307)
  17.         AND `gr4311`.`text_name` IN (4312)
  18.         AND `gr4319`.`text_name` IN (4321)
  19.         AND `gr4330`.`text_name` IN (4332)
  20.         AND `gr4323`.`text_name` IN (4324)
  21.         AND `gr4327`.`text_name` IN (4328)
  22.         AND `gr21663`.`text_name` IN (21664)
  23.  
  24.                                        
  25. ORDER BY `catalog`.`ord` DESC
  26. LIMIT 0,16;
  27.  


Это некий фильтр товаров, запрос строится динамически, на основе выбранных юзером значений фильтра. Каждый JOIN здесь - это группа фильтра (производитель, цвет и т.п.), естественно, чем больше выбрано групп, тем больше будет и JOIN.

Структура таблиц (упрощенная):

Спойлер (Отобразить)


EXPLAIN запроса:

Спойлер (Отобразить)



С увеличением количества JOIN время выполнения запроса выходит весьма значительное (от 40 сек), буду очень благодарен, если подкините идею, как это все можно оптимизировать. Этот чудесный запрос достался по наследству.

Готов так же рассмотреть изменение структуры БД.

Спасибо.
2. and_07 - 03 Февраля, 2015 - 16:47:50 - перейти к сообщению
чет не уловил зачем вы ... join
а потом ... IN (4317,4318) для каждого join

может сделать один join
и в in (...все id...)
3. evgen_dev - 03 Февраля, 2015 - 16:54:01 - перейти к сообщению
and_07 пишет:
чет не уловил зачем вы ... join
а потом ... IN (4317,4318) для каждого join

может сделать один join
и в in (...все id...)


Нет. В данном случаи так не пойдет. Ибо, например,

CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. AND `gr4301`.`text_name` IN (4302,4307)
  3. AND `gr4311`.`text_name` IN (4312)
  4.  


проверяется, (цвет: черный или белый) AND (производитель: Apple)

если оставить одни JOIN и написать так:

CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. AND `group_expl`.`text_name` IN (4302,4307,4312)
  3.  


то выходит: черный или белый или Apple
4. and_07 - 03 Февраля, 2015 - 17:05:25 - перейти к сообщению
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT * FROM TABLE
  3. WHERE text_name IN (4302,4307,4312)
  4.  


возьмет все записи у которых
text_name = 4302
text_name = 4307
text_name = 4312

+ можно переделать на связь многие ко многим

 

Powered by ExBB FM 1.0 RC1