#sql-server #stored-procedures #query-performance
#sql-сервер #хранимые процедуры #запрос-производительность
Вопрос:
У меня есть запрос, который принимает VendorID в качестве параметра, и он должен возвращать все электронные продукты этого поставщика, которые находятся в состоянии «Одобрено», а также имеют действительную запись в реестре.
Проблема в том, что у многих продуктов есть RegistryEntry, чтобы проверить, является ли этот RegistryEntry этого продукта действительным, мне нужно проверить в таблице tblRegistries с StatusID= 2, что означает, что это действительный ключ.
Приведенный ниже запрос работает нормально, меня беспокоит производительность при использовании
IN (SELECT RegistryEntry FROM tblRegistries WHERE StatusId = 2)
потому что в среде prod в таблице tblRegistries много данных, и когда я говорю
SELECT RegistryEntry FROM tblRegistries WHERE StatusId = 2
он возвращает сотни тысяч записей
SELECT * FROM [dbo].[Product] P
INNER JOIN [dbo].[ElectronicProduct] EP
ON P.ProductId = EP.ProductId
WHERE P.VendorId = @VendorId
AND P.[RegistryEntry] IN (SELECT RegistryEntry FROM tblRegistries WHERE StatusId = 2) AND EP.Status = 'Approved'
Я ищу некоторые экспертные предложения по этому поводу, если это можно сделать лучшим способом с помощью объединений или других функций.
Ответ №1:
Вы пробовали что-то подобное?
SELECT * FROM [dbo].[Product] P
INNER JOIN [dbo].[ElectronicProduct] EP ON P.ProductId = EP.ProductId
INNER JOIN tblRegistries R ON R.RegistryEntry = P.RegistryEntry AND StatusId = 2
WHERE P.VendorId = @VendorId
AND EP.Status = 'Approved'
Также добавление индекса к объединенным полям должно повысить производительность
Комментарии:
1. Привет, Acuao, спасибо за ваше предложение я попытался использовать join, и данные не совпадали, и вместо того, чтобы пытаться выяснить, в чем проблема, я просто использовал IN operator, и это моя ошибка … теперь, когда я снова изучаю это, я обнаружил, что в таблице RegistryEntry есть повторяющиеся записи для одного и того жепродукт и это вызывает дублирование в запросе result…….Is есть ли способ, которым мы можем получить только 1 продукт в результирующем наборе, даже если есть несколько записей для одного и того же продукта и StatusID = 2?
2. Вы стремитесь к отличной производительности, поэтому я бы посоветовал вам в fisrt удалить дублирующиеся данные в таблице. Если вы не можете этого сделать, вы можете использовать предложения group by и, возможно, having, но это также может снизить производительность
Ответ №2:
Я нахожу, что exists часто выполняется намного быстрее…
SELECT * FROM [dbo].[Product] P
INNER JOIN [dbo].[ElectronicProduct] EP
ON P.ProductId = EP.ProductId
WHERE P.VendorId = @VendorId
AND EXISTS (
SELECT RegistryEntry FROM tblRegistries
WHERE StatusId = 2 and RegistryEntry = P.[RegistryEntry])
Комментарии:
1. Спасибо @Northbank75, это очень полезно, так как я часто использую IN operator, и я постараюсь заменить его на Exists в дальнейшем.