Mysql. Многократный JOIN с одной и той же таблицей

Прошу помощи так как не знаю как правильно поступить.
Есть к примеру таблица
id | fk_1 | fk_2 | fk_3 | fk_4 | fk_5 | fk_6 | fk_7

И есть таблица на которую ссылаются fk_x
id | name

До поры до времени в fk_1 fk_2 и так далее хранился тупо json типа {id: 1, name: 'name'}
С одной стороны это как не странно удобно, так как когда я получаю все записи в массив я могу достучатся до значения fk_x. например
$name = $data['fk_1']['name'] ;

Фишка в том что fk_1 всегда имеет значение, а остальные не всегда

После того как я убрал JSON получается запрос
SELECT * FROM main_table as `mt`
LEFT JOIN second_table as `st_1` ON `st_1`.id = `mt`.fk_1
LEFT JOIN second_table as `st_2` ON `st_2`.id = `mt`.fk_2
LEFT JOIN second_table as `st_3` ON `st_3`.id = `mt`.fk_3
LEFT JOIN second_table as `st_4` ON `st_4`.id = `mt`.fk_4
LEFT JOIN second_table as `st_5` ON `st_5`.id = `mt`.fk_5
LEFT JOIN second_table as `st_6` ON `st_6`.id = `mt`.fk_6
LEFT JOIN second_table as `st_7` ON `st_7`.id = `mt`.fk_7


Начал тестить на 100к записях два варианта

Как не странно аналайзер мне сказал что с json запрос на выборку 100к записей работает быстрее, чем вариант c join.

Подумал и решил потестировать со всеми преобразованиями в коде, так как в случае с JSON для каждой записи в коде вызывается json_decode, а во втором случае преобразования через алиасы.

Для обратной совместимости пришлось писать в цикле для каждого джоина "алиас-префикс"
SELECT main_table.*, second_table.name as `fk_1_name`
LEFT JOIN second_table as `st_1` ON `st_1`.id = `mt`.fk_1
......

А потом в цикле преобразовать, чтобы можно было достучатся в формате
$data['fk_1']['name'] = $data['fk_1_name']

Результат показал на удивление что вариант с JSON выполняется быстрее как с преобразованиями так и без.

Подскажите, что нужно делать в таком случае. Догадываюсь что модель неправильно составлена изначально в связи с тем, что связь многие ко многим.

Извиняюсь за ошибки и пунктуацию...

Пример привел абстрактный! Вообще главная таблица - это таблица заказа трансфера
где fk_1 - Откуда заказ,
fk_2 - Куда заказ
fk_3 - Промежуточная точка 1 и так далее
  • Вопрос задан
  • 5549 просмотров
Пригласить эксперта
Ответы на вопрос 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Лучше использовать хранение в виде `id_zakaza`, `id_fk`, `order` - соответственно ID заказа, ID точки, порядковый номер точки в маршруте. В этом случае JOIN будет всего один.
Ответ написан
Мы на практике получали лучшие результаты при использовании подзапросов вместо множественных JOIN. (в сравнении с многократным JOIN с одной и той же таблицей)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы