SQL Server — выполнение запроса при использовании IN operator, когда объем данных огромен

#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 в дальнейшем.