First, here is the initial question I asked. Now suddenly the query is taking 3+ minutes to run. If I remove the final case statement at the bottom (right above FROM tau) it runs in literally 1 second.
I have rewritten my Scalar UDF to use table valued functions instead. This initially increased performance. I then created indexes on the tables. Honestly, I am not great at reading the execution plan, so I have included it below.
CODE:
-- Normalized Effectiveness score = function(Effectiveness) {CASE WHEN ??? THEN Normalized Effectiveness Score}
-- Effectiveness = (Target AHT * # Calls Handled)/Total Handle Time;
-- Weight = Eligible Calls Handled Per Split / Total Eligible Calls
-- (calls from certain skill groups are ineligible)
-- split = call reason/call type
-- Ultimate goal is to arrive at a table with one row per advocate, with a Normalized Effectiveness Score (and all component parts) for each advocate
WITH agent_split_stats AS (
Select
racf,
agent_stats.SkillTargetId,
agent_stats.SkillGroupSkillTargetID,
aht_target.EnterpriseName,
aht_target.target,
Sum(agent_stats.CallsHandled) as n_calls_handled,
CASE WHEN (Sum(agent_stats.TalkInTime) + Sum(agent_stats.IncomingCallsOnHoldTime) + Sum(agent_stats.WorkReadyTime)) = 0 THEN 1 ELSE
(Sum(agent_stats.TalkInTime) + Sum(agent_stats.IncomingCallsOnHoldTime) + Sum(agent_stats.WorkReadyTime))END
AS total_handle_time
from tblAceyusAgntSklGrp as agent_stats
-- GET TARGETS
INNER JOIN tblCrosswalkWghtPhnEffTarget as aht_target
ON aht_target.SgId = agent_stats.SkillGroupSkillTargetID
AND agent_stats.DateTime BETWEEN aht_target.StartDt and aht_target.EndDt
-- GET RACF
INNER JOIN tblAgentMetricCrosswalk as xwalk
ON xwalk.SkillTargetID = agent_stats.SkillTargetID
--GET TAU DATA LIKE START DATE AND GRADUATED FLAG
INNER JOIN tblTauClassList AS T
ON T.SaRacf = racf
WHERE DateTime >= TauStart
AND DateTime <= TauEnd
--AND Graduated = 'No'
--WPE FILTERS TO ENSURE ACCURATE DATA
AND CallsHandled <> 0
AND Target is not null
Group By
racf, agent_stats.SkillTargetId, agent_stats.SkillGroupSkillTargetID, aht_target.EnterpriseName, aht_target.target
),
agent_split_stats_with_weight AS (
-- calculate weights
-- one row = one advocate + split
SELECT
agent_split_stats.*,
agent_split_stats.n_calls_handled/SUM(agent_split_stats.n_calls_handled) OVER(PARTITION BY agent_split_stats.skilltargetid) AS [weight]
FROM agent_split_stats
),
agent_split_effectiveness AS (
-- calculate the raw Effectiveness score for each eligible advocate/split
-- one row = one agent + split, with their raw Effectiveness score and the components of that
SELECT
agent_split_stats_with_weight.*,
-- these are the components of the Effectiveness score
(((agent_split_stats_with_weight.target * agent_split_stats_with_weight.n_calls_handled) / agent_split_stats_with_weight.total_handle_time)*100)*agent_split_stats_with_weight.weight AS effectiveness_sum
FROM agent_split_stats_with_weight
), -- this is where we show effectiveness per split select * from agent_split_effectiveness
agent_effectiveness AS (
-- sum all of the individual effectiveness raw scores for each agent to get each agent's raw score
SELECT
racf AS SaRacf,
ROUND(SUM(effectiveness_sum),2) AS WpeScore
FROM agent_split_effectiveness
GROUP BY racf, skilltargetid
),
--GET FULL CLASS LIST AND TAU DATES
tau AS (
Select ID, SaRacf, FacilitatorRacf, TauSupvRacf, ClassType, TrainerType, TauStart AS TauStartDate, TauEnd, Graduated, MetGoalDate, TauYear, TermDate
FROM tblTauClassList
)
--JOIN ALL DATA TOGETHER
SELECT tau.*,
CASE WHEN WpeScore IS NULL THEN (SELECT WpeNullScore FROM tblAvs1FltrScr WHERE WpeNullScore IS NOT NULL)
ELSE WpeScore END
AS WpeScore
FROM tau
LEFT JOIN agent_effectiveness
ON agent_effectiveness.SaRacf = tau.SaRacf
ORDER BY SaRacf
Expecting the query to run <5 seconds and provide a result regardless if a person has a "WpeScore" or not. If they do not, i have a default value that gets slotted in.
It could be bad indexes, I use the bulk of this code elsewhere and it runs failrly quickly. In this instance its just totally crapping the bed on this part:
CASE WHEN WpeScore IS NULL THEN (SELECT WpeNullScore FROM tblAvs1FltrScr WHERE WpeNullScore IS NOT NULL)
ELSE WpeScore END
AS WpeScore