Первая часть запроса захватывает Policy
's Premiums
, Effective
и Expiration
. Вторая часть создает Calendar
, а третья часть (окончательная SELECT
заявление) возвращает прибыль, деактивированная Month
и Year
Все работает нормально, занимает всего 3 секунды, чтобы отобразить результат. Но тогда мне нужно отфильтровать то, что PolicyNumber
s для работы, в основном мне нужно избавиться от PolicyNumber
, у которого нет @ClassCode
. Так что в первой части запроса я поместил WHERE
пункт:Как повысить производительность запроса при использовании подзапроса
WHERE State IN ('CA','NV','AZ')
AND PolicyNumber IN (
SELECT PolicyNumber
FROM tblClassCodesPlazaCommercial
GROUP BY PolicyNumber
HAVING COUNT (CASE WHEN ClassCode NOT IN (@ClassCode)
THEN 1 END)=0
)
Thanksful для @Prdp пользователя У меня есть это заявление: Дело заявление будет генерировать 1 для ClassCode, который присутствует в списке еще NULL будет генерироваться. Теперь суммарный счетчик будет составлять 1 для каждого PolicyNumber. Установив = 0, мы можем убедиться, что PolicyNumber не содержит ClassCode в данном списке.
После этого запроса, вращающегося навсегда, becase @ClassCode
может иметь больше, чем 200 ClassCodes
в отчете SSRS.
Интересные вещи в том, что оба эти заявления работают отлично. Но когда я использую их вместе (который помещается что WHERE
положение в cte policy_data
то выполнение принимает навсегда. Есть ли способ сказать двигатель, чтобы сделать первую часть запроса, которая
; WITH Earned_to_date AS (
SELECT Cast(EOMONTH (GETDATE(), -1) AS DATE) AS Earned_to_date
), policy_data AS (
SELECT
PolicyNumber
, Cast(PolicyEffectiveDate AS DATE) AS PolicyEffectiveDate
, Cast(PolicyExpirationDate AS DATE) AS PolicyExpirationDate
, WrittenPremium
, State
FROM PlazaInsuranceWPDataSet
WHERE State IN ('CA','NV','AZ')
/* -------This statement gives me trouble ----------------------*/
AND PolicyNumber IN (
SELECT PolicyNumber
FROM tblClassCodesPlazaCommercial
GROUP BY PolicyNumber
HAVING COUNT (CASE WHEN ClassCode NOT IN (5151)
THEN 1 END)=0
)
)
А затем рассчитать и разрыв вниз Прибыль только те политики, которые были отфильтрованы
Мой весь код ниже:.
; WITH Earned_to_date AS (
SELECT Cast(EOMONTH (GETDATE(), -1) AS DATE) AS Earned_to_date
), policy_data AS (
SELECT
PolicyNumber
, Cast(PolicyEffectiveDate AS DATE) AS PolicyEffectiveDate
, Cast(PolicyExpirationDate AS DATE) AS PolicyExpirationDate
, WrittenPremium
, State
FROM PlazaInsuranceWPDataSet
WHERE State IN ('CA','NV','AZ')
/* -------This statement gives me trouble ----------------------*/
AND PolicyNumber IN (
SELECT PolicyNumber
FROM tblClassCodesPlazaCommercial
GROUP BY PolicyNumber
HAVING COUNT (CASE WHEN ClassCode NOT IN (@ClassCode)
THEN 1 END)=0
)
)
, digits AS (
SELECT digit
FROM (VALUES (0), (1), (2), (3), (4)
, (5), (6), (7), (8), (9)) AS z2 (digit)
), numbers AS (
SELECT 1000 * d4.digit + 100 * d3.digit + 10 * d2.digit + d1.digit AS number
FROM digits AS d1
CROSS JOIN digits AS d2
CROSS JOIN digits AS d3
CROSS JOIN digits AS d4
), calendar AS (
SELECT
DateAdd(month, number, '1753-01-01') AS month_of
, DateAdd(month, number, '1753-02-01') AS month_after
FROM numbers
), policy_dates AS (
SELECT
PolicyNumber
, CASE
WHEN month_of < PolicyEffectiveDate THEN PolicyEffectiveDate
ELSE month_of
END AS StartRiskMonth
, CASE
WHEN PolicyExpirationDate < month_after THEN PolicyExpirationDate
WHEN Earned_to_date.Earned_to_date < month_after THEN Earned_to_date
ELSE month_after
END AS EndRiskMonth
, DateDiff(day, PolicyEffectiveDate, PolicyExpirationDate) AS policy_days
, WrittenPremium
FROM policy_data
JOIN calendar
ON (policy_data.PolicyEffectiveDate < calendar.month_after
AND calendar.month_of < policy_data.PolicyExpirationDate)
CROSS JOIN Earned_to_date
WHERE month_of < Earned_to_date
)
SELECT
Year(StartRiskMonth) as YearStartRisk,
Month(StartRiskMonth) as MonthStartRisk,
c.YearNum,c.MonthNum,
convert(varchar(7), StartRiskMonth, 120) as RiskMonth,
sum(WrittenPremium * DateDiff(day, StartRiskMonth, EndRiskMonth)/policy_days) as EarnedPremium
FROM tblCalendar c
LEFT JOIN policy_dates l ON c.YearNum=Year(l.StartRiskMonth) AND c.MonthNum = Month(l.StartRiskMonth)
AND l.StartRiskMonth BETWEEN '01-01-2015' AND '12-31-2016'
WHERE c.YearNum Not IN (2017)
GROUP BY convert(varchar(7), StartRiskMonth, 120),
Year(StartRiskMonth) , Month(StartRiskMonth),
c.YearNum,c.MonthNum
ORDER BY c.YearNum,c.MonthNum
что бы быть лучшим способом для повышения производительности? 10 Я создал non-clustered
индекс на PolicyNumber
на обеих таблицах. Но все равно ничего. Как я уже сказал, мне кажется, что если SQL Engine обработает первую часть (фильтрация PolicyNumber), которая занимает 3 секунды, а затем сделать вторую часть (расчет для тех PolicyNumber), которая занимает еще 3 секунды - это было бы потрясающе. Но я новичок в DBA, поэтому я не уверен, что это даже возможно. Любые советы? Благодаря
Execution Plan ::
Codereview.stackexchange.com является лучшим местом для этого – scsimon