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 :: оптимизация JOIN

 PHP.SU

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


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

> Описание: когда много JOIN-в
DlTA
Отправлено: 16 Апреля, 2014 - 16:00:13
Post Id



Постоянный участник


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


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




что лучше писать запрос в котором будет прямо прописаны JOIN-ы
или многоуровневая выборка с последующими JOIN-нами?

было (Отобразить)


при выполнении с EXPLAIN показывает что везде используются ключи, количество затронутых строк максимум 400+
время выполнения запроса 0,9 сек., и вроде все хорошо и не надо было бы его трогать, НО когда сервер баз данных вешают, длительность этого запроса доходит до 15-20 сек.
результат запроса кешируется, и на самом деле выполняется раз в 15+минут, но все же

попытки оптимизировать (Отобразить)

результат получился хуже время выполнения 2+ секунды, ключи для временных таблиц не создаются, и т.д.и т.п., но вот что выдаст этот запрос при высокой нагрузке на сервер баз данных не известно, предположительно запрос пройдет быстрее, так как объем занимаемой памяти на запрос должен быть меньше, а там фиг его знает

так вот вопрос, идея верна?
ибо в одном из подобных запросов, оптимизация существенно облегчила жизнь, но там был строковый поиск
 
 Top
Мелкий Супермодератор
Отправлено: 16 Апреля, 2014 - 16:11:30
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


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




Есть мнение, что join здесь неуместен вовсе, а эффективнее будет связанный подзапрос через exists.
Не очень понял структуру таблиц, чтобы примером проиллюстрировать.


-----
PostgreSQL DBA
 
 Top
DlTA
Отправлено: 16 Апреля, 2014 - 19:19:52
Post Id



Постоянный участник


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


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




суть запроса в том что получить все марки `vendor` в которых есть товар `goods` который находится в подразделах, которые находятся в разделах `category`, которые в свою очередь принадлежат магазину с индексом 0 (`category`.`shopId` = 0)

и все это попутно повязано тем что доступ ко всем элемента/страницам идет через таблицу `hierarchy`

`hierarchy`.`intableID` указывает на id элемента в своей таблице, а `hierarchy`.`tableID` указывает на таблицу (7-товар, 39-раздел, 40-подраздел)


попутно в `hierarchy`.`parent` указан указатель на родительский элемент `hierarchy`.`id`

а про exists ща будем читать
 
 Top
SAD Модератор
Отправлено: 16 Апреля, 2014 - 19:35:03
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2508
Дата рег-ции: Май 2009  
Откуда: Днепропетровск, Украина


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




скорее всего, Вы еще не от той таблицы пляшете
 
 Top
DlTA
Отправлено: 16 Апреля, 2014 - 19:36:56
Post Id



Постоянный участник


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


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




SAD пишет:
не от той таблицы пляшете
так не понял, можно развернутей
 
 Top
SAD Модератор
Отправлено: 16 Апреля, 2014 - 21:10:58
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2508
Дата рег-ции: Май 2009  
Откуда: Днепропетровск, Украина


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




если бы я видел базу, то сказал точнее.

На будущее запомните. Выборку, по возможности, нужно начинать с той таблицы, которая отсеет больше записей(то есть на которую накладывается больше условий и т.д.)
(Добавление)
CODE (SQL):
скопировать код в буфер обмена
  1.     SELECT DISTINCT h.id, h.header
  2.       FROM category cat
  3.       LEFT JOIN hierarchy h ON h.intableID = cat.id
  4.       LEFT JOIN hierarchy h2 ON h.id = h2.parent
  5.       LEFT JOIN hierarchy h3 ON h2.id = h3.parent
  6.       LEFT JOIN goods g ON g.id = h3.intableID
  7.       LEFT JOIN vendor v ON v.id = g.vendor
  8.      WHERE cat.shopId = 0
  9.        AND h.tableID = 39
  10.        AND h2.tableID = 40
  11.        AND h3.tableID = 7
  12.        AND g.tights = 1
  13.        AND v.gray = 0
  14.      ORDER BY v.header


пальцем в небо
 
 Top
DlTA
Отправлено: 16 Апреля, 2014 - 22:44:10
Post Id



Постоянный участник


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


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




SAD пишет:
LEFT JOIN hierarchy h ON h.intableID = cat.id
      LEFT JOIN hierarchy h2 ON h.id = h2.parent
      LEFT JOIN hierarchy h3 ON h2.id = h3.parent
SAD пишет:
 AND h.tableID = 39
       AND h2.tableID = 40
       AND h3.tableID = 7

а база это дело воспринимает как 1 таблицу, или как 3?
(Добавление)
и если учест что мне не нужны NULL, обязательно писать LEFT JOIN или INNER JOIN?

(Отредактировано автором: 16 Апреля, 2014 - 22:46:03)

 
 Top
SAD Модератор
Отправлено: 17 Апреля, 2014 - 09:34:05
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2508
Дата рег-ции: Май 2009  
Откуда: Днепропетровск, Украина


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




добавьте условие в WHERE
IS NOT NULL. в чем проблема то?
(Добавление)
DlTA пишет:
а база это дело воспринимает как 1 таблицу, или как 3?


у каждой свой алиас, конечно, как 3


Вы мне ответьте лучше: это дело работает нормально или нет?
 
 Top
Мелкий Супермодератор
Отправлено: 17 Апреля, 2014 - 09:48:23
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


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




SAD пишет:
добавьте условие в WHERE
IS NOT NULL. в чем проблема то?

В том, что не нужно делать left join там, где нужен inner join.

SAD пишет:
Выборку, по возможности, нужно начинать с той таблицы, которая отсеет больше записей

Не мешайте работать оптимизатору. Он легко и быстро умеет переставлять с ног на голову весь порядок объединения таблиц, оглядываясь на кучу параметров, следить за которыми вручную бессмысленно и бесполезно. Оптимизатор тупой, но это автомат. За числами он следить умеет лучше человека.
А если уж оптимизатор тупит, то и подсказывать надо на уровне оптимизатора - Index Hint'ы и STRAIGHT_JOIN'ы.


-----
PostgreSQL DBA
 
 Top
SAD Модератор
Отправлено: 17 Апреля, 2014 - 09:58:33
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2508
Дата рег-ции: Май 2009  
Откуда: Днепропетровск, Украина


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




Могу поспорить


Если я начну выборку с таблицы, где миллион записей, и на ней либо не будет условия, либо будет условие по полю без индекса, то это будет плохой затеей. И не всегда могут подхватиться нужные индексы. На автомат надейся, а сам не плошай
 
 Top
Zuldek
Отправлено: 17 Апреля, 2014 - 09:59:22
Post Id


Постоянный участник


Покинул форум
Сообщений всего: 2122
Дата рег-ции: Июнь 2010  


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




Имхо, когда в запросе 3 раза нужно джоинить одну и ту же таблицу, структура данных в бд не оптимальна... . Согласен с Мелким: подзапросы выполнятся быстрее с exists

Цитата:
CODE (SQL):
скопировать код в буфер обмена
  1. WHERE ...
  2.        AND h.tableID = 39
  3.        AND h2.tableID = 40
  4.        AND h3.tableID = 7
  5.        AND g.tights = 1
  6.        AND v.gray = 0


Почему эти условия не перенести в джоины?

(Отредактировано автором: 17 Апреля, 2014 - 10:07:10)

 
 Top
DlTA
Отправлено: 17 Апреля, 2014 - 10:01:12
Post Id



Постоянный участник


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


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




ребята по медленней, я записываю)
(Добавление)
Мелкий пишет:
А если уж оптимизатор тупит, то и подсказывать надо на уровне оптимизатора
тут 2 вопроса, точнее 1, а как вычислить факт тупизма оптимизатора?
(Добавление)
Zuldek пишет:
Почему эти условия не перенести в джоины?
DlTA пишет:
попутно повязано тем что доступ ко всем элемента/страницам идет через таблицу `hierarchy`

`hierarchy`.`intableID` указывает на id элемента в своей таблице, а `hierarchy`.`tableID` указывает на таблицу (7-товар, 39-раздел, 40-подраздел)

(Добавление)
Zuldek пишет:
Имхо, когда в запросе 3 раза нужно джоинить одну и ту же таблицу, структура данных в бд не оптимальна.
тут не поспоришь, изначальные разработчики почему то думали что можно допустить ситуацию что к товару можно привязать раздел, а к марке рассылку, но перекраивать что то очень большое туго шевелящееся но всеже. черевато, ибо нельзя взять и остановить это дело на недельку
 
 Top
SAD Модератор
Отправлено: 17 Апреля, 2014 - 10:12:20
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2508
Дата рег-ции: Май 2009  
Откуда: Днепропетровск, Украина


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




DlTA пишет:
Почему эти условия не перенести в джоины?


Потому что могут появиться лишние NULL записи
 
 Top
DlTA
Отправлено: 17 Апреля, 2014 - 10:13:06
Post Id



Постоянный участник


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


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




SAD пишет:
DlTA пишет:
Почему эти условия не перенести в джоины?


Потому что могут появиться лишние NULL записи
это не я вопрос ставил
 
 Top
Zuldek
Отправлено: 17 Апреля, 2014 - 10:13:37
Post Id


Постоянный участник


Покинул форум
Сообщений всего: 2122
Дата рег-ции: Июнь 2010  


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




Цитата:
CODE (SQL):
скопировать код в буфер обмена
  1.     SELECT DISTINCT h.id, h.header
  2.       FROM category cat
  3.       LEFT JOIN hierarchy h ON (h.intableID = cat.id AND h.tableID = 39)
  4.       LEFT JOIN hierarchy h2 ON (h.id = h2.parent AND h2.tableID = 40)
  5.       LEFT JOIN hierarchy h3 ON (h2.id = h3.parent AND h3.tableID = 7)
  6.       LEFT JOIN goods g ON g.id = h3.intableID
  7.       LEFT JOIN vendor v ON v.id = g.vendor
  8.      WHERE cat.shopId = 0
  9. ....

?

(Отредактировано автором: 17 Апреля, 2014 - 10:36:16)

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


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



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

 
Powered by ExBB FM 1.0 RC1. InvisionExBB