db/Query и поздапросы

имеется сложный запрос с несколькими innerJoin:




$query = new Query();

...

$query->innerJoin(['phs' => '{{%vg_price_hotel_service}}'], 'phs.PriceId = prices.Id');

...



Все нормально работает.

Но необходимо добавить leftJoin, в ON условии которого имеется подзапрос вида:




LEFT JOIN [dbo].[HotelQuotas] as hqs ON hqs.Id =

(

    SELECT  TOP 1 Id

    FROM [dbo].[HotelQuotas]

    WHERE   BuildingId = blds.Id

    AND RoomCategoryId = rmcts.Id

    AND RoomTypeId = rmtps.Id

    AND TourOperatorId = prices.TourOperatorId

    AND (TypeVisit = 0 AND NOT ((DATEADD(DD, hs.Nights, prices.Date) < Date) OR (DATEADD(DD, Duration, Date) < prices.Date))

      OR TypeVisit = 1

      AND prices.Date >= Date

      AND prices.Date <= DATEADD(DD, Duration, Date)

      )

    ORDER BY Id DESC, FreeAccess ASC



все связи, blds, rmcts, rmtps, prices, hs определены в innerJoin-ах выше.

с какой стороны лучше подлезть… есть варианты? что-то не могу осилить

Могу сказать сразу что это будет тормозить если у тебя вырастет база. На сколько я знаю MySql плохо работает с подзапросами. В таких случая я обычно создаю отдельную таблицу или лучше view и туда кеширую данные. Если нельзя сделать кэш, например в тоем случае, лучше оформить это в коде. Я пробовал эксперементировать. Странно, но работает очень медленно, даже со всеми index.

Поделюсь реальным опытом.

MySQL. При таблице объёмом в 10 000 записей, время выполнения такого рода запроса составляло в среднем 20 секунд.

На данный момент таблица 3,5 млн. записей, запрос длится 3-4 секунды. Помогает кеш. Также пришлось избавиться от всех джоинов в принципе.

Вывод. Если хотябы чисто теоритически Вы планируете расширение базы данных, то откажитесь от такого подхода в mysql.

спасибо большое, что привели пример из опыта… так и есть… таблица в 132к записей жутко тормозит… а вырастет она очень быстро… буду искать другое решение ) хотя на MariaDb работает заметно быстрее… Mysql похоже и вправду с подзапросами не дружит

Я решил такую проблему через введение в sql переменных и присвоение им начальных значений. Потом в запросе используйте переменные.