Медленный запрос при использовании count (*) и внутреннего соединения - PullRequest
0 голосов
/ 04 марта 2019

Мой запрос занимает около 5 секунд.Он возвращает почти 5000 записей.

SELECT 
    c.CompanyID, 
    c.CompanyName, 
    psr.PartnerSRFName, 
    psr.PartnerSRLName, 
    be.MonthlyFee, 
    (
        SELECT Count(*) 
        FROM Units
        INNER JOIN Properties ON Units.PropertyID = Properties.PropertyID
        WHERE Properties.CompanyID = c.CompanyID
    ) TotalUnits
FROM Company c
LEFT JOIN Partner_SalesRep_CompanyMap psrcm ON c.CompanyID = psrcm.CompanyID
LEFT JOIN Partner_SalesReps psr ON psrcm.Partner_SalesRepsID = psr.AssignedID
LEFT JOIN Billing_Exemption be ON be.CompanyID = c.CompanyID
WHERE c.LeadSourceCompanyID = 1 AND Active = 1

Если я удаляю Select Count(*) ..., он работает очень быстро, но мне нужны эти данные.Есть ли способ улучшить этот запрос?

Спасибо

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Индексы, рекомендованные Гордоном Линоффом, являются обязательными.

Другая вещь, которую вы могли бы сделать, - это перенести вычисление из встроенного запроса в присоединенный подзапрос.Это может позволить СУБД оптимизировать запрос, поскольку теперь явно указывается, что нет необходимости повторять вычисления для каждой записи (на самом деле только отдельные значения CompanyID имеют значение):

SELECT 
    c.CompanyID, 
    c.CompanyName, 
    psr.PartnerSRFName, 
    psr.PartnerSRLName, 
    be.MonthlyFee, 
    COALESCE(x.TotalUnits, 0) TotalUnits
FROM Company c
LEFT JOIN Partner_SalesRep_CompanyMap psrcm ON c.CompanyID = psrcm.CompanyID
LEFT JOIN Partner_SalesReps psr ON psrcm.Partner_SalesRepsID = psr.AssignedID
LEFT JOIN Billing_Exemption be ON be.CompanyID = c.CompanyID
LEFT JOIN (
    SELECT Properties.CompanyID, COUNT(*) TotalUnits
    FROM Units
    INNER JOIN Properties ON Units.PropertyID = Properties.PropertyID
    GROUP BY Properties.CompanyID
) x ON x.CompanyID = c.CompanyID
WHERE c.LeadSourceCompanyID = 1 AND Active = 1

Другой вариант - включить слияние подзапроса с внешним запросом (добавив больше соединений к внешнему запросу), включить агрегирование всего внешнего запроса и использовать уникальный столбец в таблице Units или Properties, чтобы выполнитьсчитатьЯ не большой поклонник этого, поскольку, как правило, чем раньше вы агрегируете, тем выше эффективность.

0 голосов
/ 04 марта 2019

Для этого подзапроса:

(Select Count(*)
 From Units u join
      Properties p
      on u.PropertyID = p.PropertyID
 Where p.CompanyID = c.CompanyID
) as TotalUnits

Требуются индексы для properties(companyid, propertyid) и units(propertyid).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...