Оптимизация запроса

Vano_big

Новичок
Оптимизация запроса

В разных источниках читал, мол осторожней используйте
LEFT JOIN, нагрузка большая на систему. Тогда вопрос по теме.

Есть одна главная таблица в которой 4 поля являются индекстными.
В таком случае каким способ будет экономичнее воспользоваться. Получить нужную информацию одним запросом (используя LEFT JOIN), либо разделить все это на несколько запросов?

Заранее благодарен всем кто ответит.
 

ONK

Пассивист PHPСluba
Vano_big, Прочитай свой вопрос и скажи нам, что и с чем ты собираешся объединять? ;)
 

Vano_big

Новичок
есть таблица table1, в ней есть поля: id,a,b,c,d
a,b,c,d - это индексные поля (таблицы table2, table3, table4, table5)
SELECT t1.name, t2.val, t3.res, t4.activ, t5.action FROM table1 AS t1 LEFT JOIN table2 AS t2 ON t1.a=t2.id LEFT JOIN table3 AS t3 ON t1.b=t3.id LEFT JOIN table4 AS t4 ON t1.c=t4.id LEFT JOIN table5 AS t5 ON t1.d=t5.id WHERE t1.id = 5

Вопрос был в следующем...
Как будет оптимальнее: разбить все на отдельные запросы, либо использовать выше приведенный?
 

ONK

Пассивист PHPСluba
Конечно одним запросом будет быстрее. id разумеется тоже индексы. Кстати для данного запроса индексы по a,b,c,d в table1 ненужны.
 

Falc

Новичок
ONK
Нельзя точно сказать что эти индексы не нужны, так как оптимизатор может расположить таблиицы в другом порядке. Все зависит от данных.
 

Vano_big

Новичок
Почему же не нужны индексы?
Ведь например таблица table1 связана с таблицей table2 по приниципу многие к одному.
Если не использовать индексы, то как же тогда связать их?
 

ONK

Пассивист PHPСluba
Falc, могу лиш повторить ещё раз, для приведённого запроса индексы в table1 по перечисленным столбцам не нужны. В данном запросе объединяются все таблицы вокруг table1, все ключи для объединения таблиц извлекаются с использованием индекса table1.id а поиск записей в объединяемых таблицах идёт по индексу tableХ.id.

Vano_big, причём тут соотношение записей?, твой запрос плюёт на то, сколько записей в table2 соответствует ключу (не путать с индексом) из table1 (выбрана будет либо первая попавшаяся запись либо NULL)
 

Vano_big

Новичок
Да, ONK, ты прав, понятия я немного перепутал.
Но ответ на вопрос получил, за что большое спасибо.
 

Falc

Новичок
ONK
Так как в запросе использован не STRAIGHT_JOIN, ты не можешь знать (не видя данных) В каком порядке будут соединятся таблицы. Так что говорить точно о том какие индексы нужны будут в даном запросе точно сказать нельзя.
 

ONK

Пассивист PHPСluba
Falc, почитай для начала про работу оптимизатора, про константы (.... t1.id = 5 ), а потом подумай над смыслом вышеприведённого запроса, он даже без использование той константы в любом случае будет отработан вышеописаным мною образом.
 

Falc

Новичок
ONK
Работа оптимизатора зависит от данных.
Если хочешь я тебе приведу пример данных на которых оптимизатор поменяет порядок таблиц при выборке.
 

ONK

Пассивист PHPСluba
Falc, для данного запроса? Очень хочу, а также тест который это демонстрирует.
 

Falc

Новичок
ONK
>>а также тест который это демонстрирует.
Что демонстрирует?
 

Falc

Новичок
ONK
для данного запроса?
Запрос предлагаю упростить да 3- таблиц.
 

Falc

Новичок
Вот для такого:

SELECT *
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t1.a=t2.id
LEFT JOIN table3 AS t3 ON t1.b=t3.id
WHERE t1.id = 5


Идет?
 

ONK

Пассивист PHPСluba
>Что демонстрирует?

Демонстрирует EXPLAIN с соответствующим результатом (тест создаёт необходимые таблицы <для table1 создаются 2таблицы одна с индексами по a,b,c,d другая без индексов>, заполняет их случайными данными, делает EXPLAIN вышеприведённого запроса с обоими вариантами индексов и сравниваются результаты).

Упрощение задачи это некрасиво, но если с 5 таблицами совсем трудно разобраться, поробуй с 3 - мя.
 

Falc

Новичок
ONK
>>Упрощение задачи это некрасиво, но если с 5 таблицами совсем трудно разобраться, поробуй с 3 - мя.

Дело не в разборке, данных будет больше.
 

ONK

Пассивист PHPСluba
Ок, давай тестировать твой вариант, я согласен что с точки зрения оптимизации он аналогичен первоначальному.
 

Falc

Новичок
ONK
Твоя правда, при LEFT JOIN'ах порядок выборки из таблиц сохраняется, сначало идут выборки из таблиц которые просто соедены потом добавляются с LEFT JOIN'ом. Хотя мне в голову почему-то запало что при LEFT JOIN'не оптимизатор менял таблицы. возможно это было с RIGHT JOIN.
 

ONK

Пассивист PHPСluba
В документации сказано что при LEFT JOIN таблицы зависимые от другой таблицы читаются всегда после того как прочитана таблица от которой они зависят. Так что даже без константного параметра по ключевому столбцу таблицы table1 (который однозначтно указывает оптимизатору что надо делать выборку по индексу таблица table1) объединение всегда происходило бы вокруг этой таблицы.
 
Сверху