#javascript #mysql #node.js #typescript #performance
Вопрос:
Обзор
Компания, в которой я работаю, использует стороннюю компанию для управления/разработки нашей базы данных электронной коммерции и нашего API. У меня есть доступ только для чтения к базе данных, но с доступом для чтения я могу запросить все продукты и получить то, что мне нужно, примерно за 1 секунду.
Вопрос
На нашем бэкэнде мы используем GraphQL для связи с API, и извлечение всех продуктов из API занимает 15 секунд, полно ошибок и неприемлемо.
Цель
У меня есть довольно сложный запрос select, который я написал, и который я хочу попробовать реализовать с помощью typeorm. Мне нужен только этот один запрос для приложения.
Запрос
select a.Disabled, a.recordnumber ItemID, CASE WHEN c.ParentID IS NOT NULL THEN 'IS Parent' ELSE 'IS NOT Parent' END AS ParentItem, a.SKU, b.ProductName, b.Description, a.Image MainImage, b.LanguageCode, a.CategoryID, a.SortOrder, a.Weight, a.Height, a.Length, a.Width, a.last_modified, a.FlagCancer, a.FlagBirthDefects, d.recordnumber DiscountID, d.last_modified DiscountIDUpdated, e.AssociateTypeID PriceGroupID, f.OrderTypeID, g.RegionID, h.StoreID, d.Start DiscountStart, d.[End] DiscountEnd, d.Price, d.PriceCurrency, d.CV, d.QV, d.RewardPointsEarned RewardPoints from INV_Inventory a join INV_LanguageValues b on a.recordnumber = b.ItemID left join ( select a.ItemID ParentID from INV_OptionItemsKeys a group by a.ItemID ) c on a.recordnumber = c.ParentID join INV_Discounts d on a.recordnumber = d.ItemID join INV_Discount_ATypes e on d.recordnumber = e.DiscountID join INV_Discount_OrderTypes f on d.recordnumber = f.DiscountID join INV_Discount_Regions g on d.recordnumber = g.DiscountID join INV_Discount_StoreMap h on d.recordnumber = h.DiscountID where c.ParentID is not null and b.LanguageCode = 'en' and g.RegionID = 1
Если у вас есть какие-либо лучшие идеи о том, как это сделать, я определенно весь внимание, и любая помощь будет признательна.
Комментарии:
1. Можете ли вы обойти фреймворк и использовать «сырой» SQL?
Ответ №1:
(Пожалуйста, не используйте псевдоним повторно ( a
); это затрудняет следование SQL.)
Рассмотрим следующую модификацию. Вместо этого выражения
CASE WHEN c.ParentID IS NOT NULL THEN 'IS Parent' ELSE 'IS NOT Parent' END AS ParentItem,
плюс это LEFT JOIN
left join ( SELECT a.ItemID ParentID from INV_OptionItemsKeys a group by a.ItemID ) c ON a.recordnumber = c.ParentID
Просто имейте это выражение:
IF ( EXISTS( SELECT 1 FROM INV_OptionItemsKeys WHERE ItemID = a.recordnumber ), 'IS Parent', 'IS NOT Parent' ) AS ParentItem,
(Возможно, это можно перепроектировать в тип.)
С другой стороны, с тех пор как вы это сделали c.ParentID is not null
, IS Parent
это всегда так??
Некоторые из этих индексов могут быть полезны:
b: INDEX(LanguageCode, ItemID, ProductName, Description) d: INDEX(ItemID) e: INDEX(DiscountID, AssociateTypeID) f: INDEX(DiscountID, OrderTypeID) g: INDEX(RegionID, DiscountID) h: INDEX(DiscountID, StoreID) INV_OptionItemsKeys INDEX(ItemID)