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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Оптимизация запроса

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
evgen_dev
Отправлено: 03 Февраля, 2015 - 16:31:22
Post Id


Новичок


Покинул форум
Сообщений всего: 3
Дата рег-ции: Апр. 2014  


Помог: 0 раз(а)




Приветствую. Есть вот такой запрос:

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 сек), буду очень благодарен, если подкините идею, как это все можно оптимизировать. Этот чудесный запрос достался по наследству.

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

Спасибо.

(Отредактировано автором: 03 Февраля, 2015 - 17:14:24)

 
 Top
and_07
Отправлено: 03 Февраля, 2015 - 16:47:50
Post Id


Гость


Покинул форум
Сообщений всего: 91
Дата рег-ции: Сент. 2012  


Помог: 3 раз(а)




чет не уловил зачем вы ... join
а потом ... IN (4317,4318) для каждого join

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

(Отредактировано автором: 03 Февраля, 2015 - 16:48:09)

 
 Top
evgen_dev
Отправлено: 03 Февраля, 2015 - 16:54:01
Post Id


Новичок


Покинул форум
Сообщений всего: 3
Дата рег-ции: Апр. 2014  


Помог: 0 раз(а)




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
 
 Top
and_07
Отправлено: 03 Февраля, 2015 - 17:05:25
Post Id


Гость


Покинул форум
Сообщений всего: 91
Дата рег-ции: Сент. 2012  


Помог: 3 раз(а)




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

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

(Отредактировано автором: 03 Февраля, 2015 - 17:13:01)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Работа с СУБД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB