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 :: Версия для печати :: оптимизация JOIN
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » оптимизация JOIN

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

1. DlTA - 16 Апреля, 2014 - 16:00:13 - перейти к сообщению
что лучше писать запрос в котором будет прямо прописаны JOIN-ы
или многоуровневая выборка с последующими JOIN-нами?

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


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

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

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

так вот вопрос, идея верна?
ибо в одном из подобных запросов, оптимизация существенно облегчила жизнь, но там был строковый поиск
2. Мелкий - 16 Апреля, 2014 - 16:11:30 - перейти к сообщению
Есть мнение, что join здесь неуместен вовсе, а эффективнее будет связанный подзапрос через exists.
Не очень понял структуру таблиц, чтобы примером проиллюстрировать.
3. DlTA - 16 Апреля, 2014 - 19:19:52 - перейти к сообщению
суть запроса в том что получить все марки `vendor` в которых есть товар `goods` который находится в подразделах, которые находятся в разделах `category`, которые в свою очередь принадлежат магазину с индексом 0 (`category`.`shopId` = 0)

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

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


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

а про exists ща будем читать
4. SAD - 16 Апреля, 2014 - 19:35:03 - перейти к сообщению
скорее всего, Вы еще не от той таблицы пляшете
5. DlTA - 16 Апреля, 2014 - 19:36:56 - перейти к сообщению
SAD пишет:
не от той таблицы пляшете
так не понял, можно развернутей
6. SAD - 16 Апреля, 2014 - 21:10:58 - перейти к сообщению
если бы я видел базу, то сказал точнее.

На будущее запомните. Выборку, по возможности, нужно начинать с той таблицы, которая отсеет больше записей(то есть на которую накладывается больше условий и т.д.)
(Добавление)
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


пальцем в небо
7. DlTA - 16 Апреля, 2014 - 22:44:10 - перейти к сообщению
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?
8. SAD - 17 Апреля, 2014 - 09:34:05 - перейти к сообщению
добавьте условие в WHERE
IS NOT NULL. в чем проблема то?
(Добавление)
DlTA пишет:
а база это дело воспринимает как 1 таблицу, или как 3?


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


Вы мне ответьте лучше: это дело работает нормально или нет?
9. Мелкий - 17 Апреля, 2014 - 09:48:23 - перейти к сообщению
SAD пишет:
добавьте условие в WHERE
IS NOT NULL. в чем проблема то?

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

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

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


Если я начну выборку с таблицы, где миллион записей, и на ней либо не будет условия, либо будет условие по полю без индекса, то это будет плохой затеей. И не всегда могут подхватиться нужные индексы. На автомат надейся, а сам не плошай
11. Zuldek - 17 Апреля, 2014 - 09:59:22 - перейти к сообщению
Имхо, когда в запросе 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


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

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

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


Потому что могут появиться лишние NULL записи
14. DlTA - 17 Апреля, 2014 - 10:13:06 - перейти к сообщению
SAD пишет:
DlTA пишет:
Почему эти условия не перенести в джоины?


Потому что могут появиться лишние NULL записи
это не я вопрос ставил
15. Zuldek - 17 Апреля, 2014 - 10:13:37 - перейти к сообщению
Цитата:
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. ....

?

 

Powered by ExBB FM 1.0 RC1