Optimize query with multiple calls to the same table - sql-server

We are creating a view as follows:
create view [dca].[CodeDescriptions_VW]
as
select distinct
ek.EmpKey
, RTRIM(CONVERT(varchar(60), abt.fdesc)) AS AboriginalTypeDescription
, RTRIM(CONVERT(varchar(60), cma.fdesc)) AS CensusMetroAreaDescription
, RTRIM(CONVERT(varchar(60), q.c_desc)) AS CobraCodeDescription
, RTRIM(CONVERT(varchar(60), ct.fdesc)) AS ConsentTypeDescription
, RTRIM(CONVERT(varchar(60), li.fdesc)) AS DirectOrIndirectDescription
, RTRIM(CONVERT(varchar(60), dt.fdesc)) AS DisabilityTypeDescription
, RTRIM(CONVERT(varchar(60), doca.fdesc)) AS DocumentADescription
FROM
dbo.hrpersnl AS h
INNER JOIN
HRActions.dbo.EmployeeKey AS ek ON RTRIM(LTRIM(UPPER(h.p_empno))) = UPPER(ek.EmpNo) COLLATE SQL_Latin1_General_CP1_CI_AS
AND h.p_company = ek.Company COLLATE SQL_Latin1_General_CP1_CI_AS
LEFT OUTER JOIN
dbo.hrtables AS abt ON abt.ftable = ''AL'' AND RTRIM(h.p_abotype) = RTRIM(abt.code)
LEFT OUTER JOIN
dbo.hrtables AS cma ON cma.ftable = ''CM'' AND RTRIM(h.p_cma) = RTRIM(cma.code)
LEFT OUTER JOIN
dbo.hrtables AS ct ON ct.ftable = ''CS'' AND RTRIM(h.p_constype) = RTRIM(ct.code)
LEFT OUTER JOIN
dbo.hrtables AS li ON li.ftable = ''IN'' AND RTRIM(h.p_laborind) = RTRIM(li.code)
LEFT OUTER JOIN
dbo.hrtables AS dt ON dt.ftable = ''DI'' AND RTRIM(h.p_distype) = RTRIM(dt.code)
LEFT OUTER JOIN
dbo.hrtables AS doca ON doca.ftable = ''I2'' AND RTRIM(h.p_doca) = RTRIM(doca.code)
I am wondering if there is a more efficient way to reference the same table (dbo.hratables) multiple times. As is, this is a very costly view (there are actually about 3 dozen different 'Descriptions' that we need to query, I have only shown a few).

While not ideal, perhaps you could create an in-line TVF and use that vs all the joins.
Something like:
CREATE FUNCTION dbo.HRDescription (
#ftable VARCHAR(2), #code VARCHAR(50), #field VARCHAR(50)
)
RETURNS TABLE
AS
RETURN
(
SELECT RTRIM( CONVERT( VARCHAR(60),
CASE
WHEN #field = 'c_desc' THEN c_desc
ELSE fdesc
END ) ) AS [Value]
FROM dbo.hrtables
WHERE
ftable = #ftable AND RTRIM( code ) = #code
)
GO
And then modify your query:
SELECT DISTINCT
ek.EmpKey
, ( SELECT [Value] FROM dbo.HRDescription( 'AL', h.p_abotype, 'fdesc' ) ) AS AboriginalTypeDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'CM', h.p_cma, 'fdesc' ) ) AS CensusMetroAreaDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'CS', h.p_constype, 'fdesc' ) ) AS ConsentTypeDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'IN', h.p_laborind, 'fdesc' ) ) AS DirectOrIndirectDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'DI', h.p_distype, 'fdesc' ) ) AS DisabilityTypeDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'I2', h.p_doca, 'fdesc' ) ) AS DocumentADescription
FROM dbo.hrpersnl AS h
INNER JOIN HRActions.dbo.EmployeeKey AS ek
ON RTRIM(LTRIM(UPPER(h.p_empno))) = UPPER(ek.EmpNo) COLLATE SQL_Latin1_General_CP1_CI_AS
AND h.p_company = ek.Company COLLATE SQL_Latin1_General_CP1_CI_AS;
Again, not ideal, but it may save on performance over the joins.

Related

SSRS- multi value report data does not display in tablix

below is my stored proc.
ALTER PROCEDURE [dbo].[Rpt_ProgramActivityReport ]
(
#StartDate DATETIME ,
#EndDate DATETIME ,
#RegionId varchar(25) = NULL,
#OrganizationId varchar(25) = NULL ,
#County varchar(25) = NULL,
#ActivityId varchar(25) = NULL,
#InterventionId varchar(25) = NULL,
#Status varchar(25) = NULL,
#StrategyId varchar(25) = NULL,
#MethodApproachId varchar(25) = NULL,
#TargetPopulationId varchar(25) = NULL,
#PrimaryProblemId varchar(25) = NULL,
#SecondaryProblemId varchar(25) = NULL,
#InterveningVariableId varchar(25) = NULL,
#FundingSourceId varchar(25)= NULL
)
AS
BEGIN
SELECT
FACT.Id fActivityId, FACT.ActivityName,
ACT.fOrganizationRegion_Id ,ACT.Id AS ActivityId,ACT.CreateUserId,
(US.LastName + ',' +US.FirstName)AS UserName,
REG.Id AS RegionId,REG.OrganizationName AS RegionName,
ORG.Id AS OrganizationId , ORG.OrganizationName AS OrganizationName,
FC.Id AS FundingSourceId, fc.FundingSource,
CA.Id AS CoverageAreaId, CA.County , CA.ZipCode
FROM Activities ACT
JOIN fActivity FACT ON FACT.Id = ACT.fActivity_Id
JOIN fOrganizationRegion ORGREG ON ORGREG.Id = ACT.fOrganizationRegion_Id
JOIN fOrganization REG ON REG.Id = ORGREG.RegionOrg_Id
JOIN fOrganization ORG ON ORG.Id = ORGREG.Org_Id
JOIN ActivityFundingSource AFC ON AFC.Activity_Id = ACT.Id
JOIN fFundingSource FC ON FC.Id = AFC.FundingSource_Id
JOIN ActivityCoverageArea ACA ON ACA.Activity_Id = ACT.Id
JOIN fCoverageAreas CA ON CA.Id = ACA.CoverageArea_Id
JOIN Users US ON US.UserId = ACT.CreateUserId
LEFT JOIN fInterventionType ITYPE ON ITYPE.Id = FACT.InterventionType_Id
LEFT JOIN ActivityInterveningVariable AIVAR ON AIVAR.Activity_Id = ACT.Id
LEFT JOIN fInterveningVariables IVAR ON IVAR.Id = AIVAR.fInterveningVariable_Id
LEFT JOIN ActivitySecondaryPriorityProblem ASPP ON ASPP.Activity_Id = ACT.Id
LEFT JOIN fPriorityProblem PP ON PP.Id = ASPP.fPriorityProblem_Id
LEFT JOIN fMethodApproach MA ON MA.Id = ACT.fMethodApproach_Id
LEFT JOIN fStrategyMethodApproach SMA ON SMA.fMethodApproach_Id = MA.Id
LEFT JOIN fStrategy ST ON ST.Id = SMA.fStrategy_Id
LEFT JOIN ActivityTargetPopulation ATP ON ATP.Activity_Id = ACT.Id
LEFT JOIN fTargetPopulation TP ON TP.Id = ATP.TargetPopulation_Id
WHERE
(Act.CreateDate BETWEEN #StartDate AND #EndDate)
AND ( (#RegionId IS NULL) OR REG.Id IN( SELECT * FROM dbo.FnSplit(#RegionId ,',' )) )
AND ((#OrganizationId IS NULL) OR ORG.Id IN ( SELECT * FROM dbo.FnSplit( #OrganizationId ,',' )))
AND ( (#County IS NULL) OR CA.County IN ( SELECT * FROM dbo.FnSplit( #County,',' ) ))
AND ((#ActivityId IS NULL) OR FACT.Id IN ( SELECT * FROM dbo.FnSplit( #ActivityId ,',' ) ) )
AND ( (#FundingSourceId IS NULL) OR FC.Id IN ( SELECT * FROM dbo.FnSplit(#FundingSourceId ,',' )) )
--AND ((#Status IS NULL) OR ACT.Completed IN (SELECT * FROM dbo.FnSplit( #Status ,',' )))
AND ((#Status IS NULL) OR ACT.Completed IN (SELECT * FROM dbo.FnSplit( cast(#Status as varchar) ,',' )))
AND ((#InterventionId IS NULL) OR ITYPE.Id IN ( SELECT * FROM dbo.FnSplit( #InterventionId ,',' ) ))
AND ((#InterveningVariableId IS NULL) OR IVAR.Id IN (SELECT * FROM dbo.FnSplit( #InterveningVariableId ,',' ) ))
AND ((#SecondaryProblemId IS NULL) OR PP.Id IN (SELECT * FROM dbo.FnSplit(#SecondaryProblemId ,',' )))
AND ((#PrimaryProblemId IS NULL) OR PP.Id IN (SELECT * FROM dbo.FnSplit( #PrimaryProblemId ,',' )))
AND ((#MethodApproachId IS NULL) OR MA.Id IN ( SELECT * FROM dbo.FnSplit(#MethodApproachId ,',' ) ))
AND ((#StrategyId IS NULL) OR ST.Id IN ( SELECT * FROM dbo.FnSplit(#StrategyId ,',' )))
AND ( (#TargetPopulationId IS NULL) OR TP.Id IN (SELECT * FROM dbo.FnSplit(#TargetPopulationId,',' )))
END
when I run it i see data.
also I have a report where I use the same stored proc in data set.
while I execute the data set I get the records.
but when I add the fields to the report tablix. it returns NO Records.
I Have also modified and checked the data with using the below codes in parameters in data set.
=Join(Parameters!RegionId.Value,",")
=Join(Parameters!OrganizationId.Value ,",")
=Join(Parameters!County.Value,",")
=Join(Parameters!ActivityId.Value,",")
=Join(Parameters!InterventionId.Value,",")
=Join(Parameters!Status.Value,",")
=Join(Parameters!StrategyId.Value,",")
=Join(Parameters!MethodApproachId.Value,",")
= Join(Parameters!TargetPopulationId.Value,",")
= Join(Parameters!PrimaryProblemId.Value,",")
= Join(Parameters!SecondaryProblemId.Value,",")
= Join(Parameters!InterveningVariableId.Value,",")
= Join(Parameters!FundingSourceId.Value,",")
but issue is I still get the records when i execute the data set separately . but in report tablix it does not display the data.
Can any one help me on this.??

How To Populate A Local Table?

I have a stored-procedure that (tries) to assign a table (derived from a query) into a variable called #relation. Here's my current futile attempt:
ALTER PROCEDURE [dbo].[getAllBookings]
#mode INT
AS
BEGIN
SET NOCOUNT ON;
--==========
DECLARE #relation AS TABLE(
id INT PRIMARY KEY, code VARCHAR(10), [description] VARCHAR(255),
environment VARCHAR(10), systems VARCHAR(50), [start] SMALLDATETIME,
[end] SMALLDATETIME, [user] VARCHAR(50), approved BIT, rejected BIT
);
SELECT * INTO [#relation] FROM
SELECT
B_ID AS 'id',
B_Change_ID AS 'code',
B_Description AS 'description',
E_Name AS 'environment',
S_System_Name AS 'systems',
dbo.fromDateTime(B_Start_Date) AS 'start',
dbo.fromDateTime(B_End_Date) AS 'end',
U_Name AS 'user',
dbo.isAppr(B_Reviewed, B_Confirmed) AS 'approved',
dbo.isRej(B_Reviewed, B_Confirmed) AS 'rejected'
FROM ((((dbo.Bookings INNER JOIN dbo.Users ON B_User_ID = U_ID)
INNER JOIN dbo.Environment ON B_Environment_ID = E_ID)
INNER JOIN dbo.BookingApps ON B_ID = BA_bookingID)
INNER JOIN dbo.EnvironmentSystems ON BA_bookingSystemID = ES_ID)
INNER JOIN dbo.System_List ON ES_SystemID = S_ID;
--==========
IF (#mode = 0)
DELETE FROM #relation WHERE (approved = 0);
SELECT * FROM #relation;
END
What am I doing wrong here?
I haven't tried building data and running it, but I had to make the following mods to get it to compile. Perhaps this will help get you started.
CREATE PROCEDURE [dbo].[getAllBookings] #mode INT
AS
BEGIN
SET NOCOUNT ON;
--==========
DECLARE #relation AS TABLE
(
[id] INT PRIMARY KEY
, [code] VARCHAR(10)
, [description] VARCHAR(255)
, [environment] VARCHAR(10)
, [systems] VARCHAR(50)
, [start] SMALLDATETIME
, [end] SMALLDATETIME
, [user] VARCHAR(50)
, [approved] BIT
, [rejected] BIT
);
INSERT INTO #relation
([id]
, [code]
, [description]
, [environment]
, [systems]
, [start]
, [end]
, [user]
, [approved]
, [rejected])
SELECT [B_ID] AS 'id'
, [B_Change_ID] AS 'code'
, [B_Description] AS 'description'
, [E_Name] AS 'environment'
, [S_System_Name] AS 'systems'
, dbo.fromDateTime([B_Start_Date]) AS 'start'
, dbo.fromDateTime([B_End_Date]) AS 'end'
, [U_Name] AS 'user'
, dbo.isAppr([B_Reviewed], [B_Confirmed]) AS 'approved'
, dbo.isRej([B_Reviewed], [B_Confirmed]) AS 'rejected'
FROM dbo.[Bookings]
INNER JOIN dbo.[Users]
ON [B_User_ID] = [U_ID]
INNER JOIN dbo.[Environment]
ON [B_Environment_ID] = [E_ID]
INNER JOIN dbo.[BookingApps]
ON [B_ID] = [BA_bookingID]
INNER JOIN dbo.[EnvironmentSystems]
ON [BA_bookingSystemID] = [ES_ID]
INNER JOIN dbo.[System_List]
ON [ES_SystemID] = [S_ID];
--==========
IF ( #mode = 0 )
DELETE FROM #relation
WHERE ( [approved] = 0 );
SELECT *
FROM #relation;
END

Why UNION used in a stored procedure in derived table?

I am not author of the stored procedure and I am wondering why they used UNION in SELECT statement when selecting from the derived table ...
If I comment out the whole UNION ALL SELECT statement, I get the same result with the same basically performance.
So I am just wonder why it is there? What kind of trick does it makes?
Below is the whole stored procedure in case I am missing something
ALTER PROCEDURE [dbo].[rptActivityLog] --'1/1/2016', '2/3/2016'
(#DateFrom datetime = null,
#DateTo datetime = null,
#UserGuid uniqueidentifier = null,
#CurrentUserGuid uniqueidentifier = NULL)
AS
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE #UserID SMALLINT
SELECT #UserID = UserID
FROM tblUsers
WHERE (UserGUID = #UserGuid)
DECLARE #ValidOfficeGuids TABLE (OfficeGuid uniqueidentifier primary key)
--if user is in tblUserQuotingOffice then use only that Office
--otherwise they will have access to all offices
IF EXISTS (SELECT OfficeGuid
FROM tblUserQuotingOffice
WHERE UserGuid = #CurrentUserGuid)
BEGIN
INSERT INTO #ValidOfficeGuids
SELECT OfficeGuid
FROM tblUserQuotingOffice
WHERE UserGuid = #CurrentUserGuid
END
ELSE
BEGIN
INSERT INTO #ValidOfficeGuids
SELECT OfficeGUID
FROM tblClientOffices
END
DECLARE #compareDateFrom DATETIME
set #compareDateFrom = CAST(CONVERT(VARCHAR(50), #DateFrom, 101) AS DATETIME)
declare #compareDateTo datetime
set #compareDateTo = DateAdd(ms, -2, DateAdd(d, 1, CAST(CONVERT(VARCHAR(50), DATEADD(day, 7, #DateTo), 101) AS DATETIME)))
--First get the log entries
declare #logResults table
(
ID int primary key not null
, IdentifierGuid uniqueidentifier
)
insert into #logResults
select
l.ID
, l.IndentifierGuid
from
tblLog l
where
l.ActionDate between #compareDateFrom and #compareDateTo
and l.IndentifierGuid is not null
select
distinct
T.UserName
, T.ControlNo
, T.InsuredPolicyName
, Replace(Replace(T.[Action],Char(10),''),Char(13),'') as [Action]
, T.ActionDate
, T.LineName as LOB
from
(
select
u.UserName
, q.ControlNo
, q.InsuredPolicyName
, l.[Action]
, l.ActionDate
, ll.LineName
, l.UserID
from
#logResults r
inner join tblLog l on r.ID = l.ID
inner join tblUsers u on l.UserID = u.UserID
inner join tblQuotes q on r.IdentifierGuid = q.QuoteGUID
inner join lstLines ll on q.LineGUID = ll.LineGUID
-- WHY DO WE USE BELOW UNION STATEMENT??????????????????????????????????
union
select
u.UserName
, q.ControlNo
, q.InsuredPolicyName
, l.[Action]
, l.ActionDate
, ll.LineName
, l.UserID
from
#logResults r
inner join tblLog l on r.ID = l.ID
inner join tblUsers u on l.UserID = u.UserID
inner join tblQuotes q on r.IdentifierGuid = q.ControlGUID
inner join lstLines ll on q.LineGUID = ll.LineGUID
) T
WHERE IsNull(#UserID, T.UserID) = T.UserID
order by
T.ActionDate
There is a difference in the join with tblQuotes, looks like the union is meant to union two different datasets (one for QuoteGUIDs and one for ControlGUIDs)

high number of reads in SQL Profiler but not when enabling Statistics

I am trying to troubleshoot a procedure that has a high number of reads in SQL Profiler, but not when I enable Statistics. It is a procedure that uses paging, and I am seeing about 17k reads on page 400 for instance, and the interesting part is that sometimes when I recompile the procedure that number drops to 1000-2000 as you can see in the screenshot. Lower pages show 1000 reads, with the number increasing as I move up:
Using SET STATISTICS IO ON in SSMS shows approximately 1000 reads even when Profiler says there are 17k:
And here is part of the procedure (the #users temp table has 4000 records in it):
SELECT [temp].[UserID] ,
[temp].[UserName] ,
[temp].[FirstName] ,
[temp].[LastName] ,
[temp].[CommissionRate] ,
[temp].[PhotoURL] ,
[temp].[UserStatusID] ,
[temp].[UserStatus] ,
[temp].[ReceivesCommission] ,
[temp].[CreatedDateTimeUTC] ,
[temp].[UserTypeID] ,
[temp].[UserType] ,
[temp].[CompanyID] ,
[temp].[CompanyName] ,
[temp].[CompanyLegalName] ,
[temp].[CompanyShortName] ,
[aggregate].[EmailAddress] ,
[aggregate].[TelephoneCount] ,
[aggregate].[Telephone] ,
[aggregate].[EmailAddressCount] ,
[address].[Address1] ,
[address].[Address2] ,
[address].[City] ,
[address].[State] ,
[address].[ZipCode]
FROM ( SELECT [user].[UserID] ,
[user].[UserName] ,
[contact].[FirstName] ,
[contact].[LastName] ,
[user].[CommissionRate] ,
[user].[PhotoURL] ,
[userStatus].[UserStatusID] ,
[userStatus].[UserStatus] ,
[user].[ReceivesCommission] ,
[user].[CreatedDateTimeUTC] ,
[userType].[UserTypeID] ,
[userType].[UserType] ,
[user].[CompanyID] ,
[user].[CompanyName] ,
[user].[CompanyLegalName] ,
[user].[CompanyShortName]
FROM [#users] [user]
INNER JOIN [dbo].[UserStatus] [userStatus] ON [userStatus].[UserStatusID] = [user].[UserStatusID]
INNER JOIN [dbo].[UserType] [userType] ON [user].[UserTypeID] = [userType].[UserTypeID]
INNER JOIN [dbo].[Contact] [contact] ON [contact].[ContactID] = [user].[UserID]
AND [contact].[ContactTypeID] = 3
WHERE ( #UserName IS NULL OR [user].[UserName] LIKE '%' + #UserName + '%' )
AND ( #FirstName IS NULL OR [contact].[FirstName] LIKE '%' + #FirstName + '%' )
AND ( #LastName IS NULL OR [contact].[LastName] LIKE '%' + #LastName + '%' )
AND ( #CompanyID IS NULL OR [user].[CompanyID] = #CompanyID )
AND ( #UserStatusID IS NULL OR [user].[UserStatusID] = #UserStatusID )
ORDER BY [contact].[LastName] ,
[contact].[FirstName] ,
[user].[CompanyName] ,
[user].[UserID] DESC
OFFSET ( #PageNumber - 1 ) * #PageSize ROWS
FETCH NEXT #PageSize ROWS ONLY
) [temp]
CROSS APPLY [dbo].[fnContactDetailAggregateGetByContactID]([temp].[UserID]) [aggregate]
LEFT JOIN [dbo].[ContactAddress] [address] ON [address].[ContactID] = [temp].[UserID]
Here is the function:
CREATE FUNCTION [dbo].[fnContactDetailAggregateGetByContactID]
(
#ContactID INT
)
RETURNS #contact TABLE
(
[ContactID] INT PRIMARY KEY NOT NULL ,
[TelephoneCount] INT NULL ,
[Telephone] VARCHAR(255) NULL ,
[EmailAddressCount] INT NULL ,
[EmailAddress] VARCHAR(255) NULL
)
WITH SCHEMABINDING
AS
BEGIN
INSERT #contact
SELECT #ContactID ,
SUM(CASE WHEN [temp].[ContactDetailTypeID] = 1 THEN 1
ELSE 0
END) [TelephoneCount] ,
MAX(CASE WHEN [temp].[ContactDetailTypeID] = 1
THEN [temp].[ContactDetailValue]
END) [Telephone] ,
SUM(CASE WHEN [temp].[ContactDetailTypeID] = 3 THEN 1
ELSE 0
END) [EmailAddressCount] ,
MAX(CASE WHEN [temp].[ContactDetailTypeID] = 3
THEN [temp].[ContactDetailValue]
END) [EmailAddress]
FROM ( SELECT [detail].[ContactID] ,
[label].[ContactDetailTypeID] ,
FIRST_VALUE([detail].[ContactDetailValue]) OVER ( PARTITION BY [label].[ContactDetailTypeID] ORDER BY [detail].[Default] DESC ) [ContactDetailValue]
FROM [dbo].[ContactDetail] [detail]
INNER JOIN [dbo].[ContactDetailLabel] [label] ON [label].[ContactDetailLabelID] = [detail].[ContactDetailLabelID]
WHERE [detail].[ContactID] = #ContactID
) [temp]
RETURN
END
Any ideas what could be causing this and how I can go about fixing it?
SELECT
t.*,
ut.[userType],
us.[userStatus],
g.[EmailAddress],
g.[TelephoneCount],
g.[Telephone],
g.[EmailAddressCount],
a.[Address1],
a.[Address2],
a.[City],
a.[State],
a.[ZipCode]
FROM (
SELECT
u.*,
c.[FirstName],
c.[LastName],
u.[CommissionRate],
u.[PhotoURL],
u.[UserStatusID],
u.[ReceivesCommission],
u.[CreatedDateTimeUTC],
u.[UserTypeID],
u.[CompanyID],
u.[CompanyName],
u.[CompanyLegalName],
u.[CompanyShortName]
FROM #users u
JOIN dbo.contact c ON c.[ContactID] = u.[UserID] AND c.[ContactTypeID] = 3
WHERE
(#UserName IS NULL OR u.[UserName] LIKE '%' + #UserName + '%')
AND (#FirstName IS NULL OR c.[FirstName] LIKE '%' + #FirstName + '%')
AND (#LastName IS NULL OR c.[LastName] LIKE '%' + #LastName + '%')
AND (#CompanyID IS NULL OR u.[CompanyID] = #CompanyID)
AND (#UserStatusID IS NULL OR u.[UserStatusID] = #UserStatusID)
ORDER BY
c.[LastName],
c.[FirstName],
u.[CompanyName],
u.[UserID] DESC
OFFSET (#PageNumber - 1) * #PageSize ROWS FETCH NEXT #PageSize ROWS ONLY
) t
JOIN dbo.userStatus us ON us.[UserStatusID] = u.[UserStatusID]
JOIN dbo.userType ut ON u.[UserTypeID] = ut.[UserTypeID]
CROSS APPLY (
SELECT
COUNT(CASE WHEN [temp].[ContactDetailTypeID] = 1 THEN 1 END) AS [TelephoneCount],
MAX(CASE WHEN [temp].[ContactDetailTypeID] = 1 THEN [temp].[ContactDetailValue] END) AS [Telephone],
COUNT(CASE WHEN [temp].[ContactDetailTypeID] = 3 THEN 1 END) AS [EmailAddressCount],
MAX(CASE WHEN [temp].[ContactDetailTypeID] = 3 THEN [temp].[ContactDetailValue] END) AS [EmailAddress]
FROM (
SELECT
[detail].[ContactID],
[label].[ContactDetailTypeID],
FIRST_VALUE([detail].[ContactDetailValue]) OVER (PARTITION BY [label].[ContactDetailTypeID] ORDER BY [detail].[default] DESC) [ContactDetailValue]
FROM [dbo].[ContactDetail] [detail]
JOIN [dbo].[ContactDetailLabel] [label] ON [label].[ContactDetailLabelID] = [detail].[ContactDetailLabelID]
WHERE [detail].[ContactID] = t.[UserID]
) [temp]
) g
LEFT JOIN dbo.ContactAddress a ON a.ContactID = t.UserID
OPTION(RECOMPILE)

Performance issue because of left join and multiple where clause

Here is the procedure
create PROCEDURE [dbo].[sample1] (
#param1 varchar(20) ,
#param2 VARCHAR(5),
#param3 varchar(max) = NULL,
#param4 varchar(max) = NULL,
#param5 varchar(max) = NULL,
#param6 bit = 1,
#param7 varchar(max) = NULL,
#param8 bit = 1,
#param9 varchar(max) = NULL,
#param10 varchar(max) = NULL,
#param11 varchar(max) = NULL,
#param12 varchar(5) = 'OP',
#param13 varchar(max) = NULL,
#TOP int = 101,
#SORTFIELD varchar(20) = 'DESCRIPTION',
#SORTDIRECTION varchar(5) = 'ASC'
)
AS
BEGIN
DECLARE
#NOW VARCHAR(10)=(SELECT CONVERT(varchar(10), GETDATE(), 112)),
#PHYSNAME VARCHAR(50)='',
#PHYPARAMS CHAR(1)='N'
/*********************************/
SELECT CPPACKAGE_PARAMS, MIN(CODE) AS MinCode, MAX(CODE) AS MaxCode
INTO #SNCPPKG_PARAMS_DTLS
FROM SNCPPKG_PARAMS_DTLS
WHERE CODETYPE = 5
GROUP BY CPPACKAGE_PARAMS
SELECT *
INTO #SNCPPACKAGERL
FROM SNCPPACKAGERL
WHERE DOMDEF = #param1
--SELECT *
--INTO #SNCPPROCDEF
--FROM SNCPPROCDEF
--WHERE DOMDEF = #param1
--SELECT *
--INTO #SNCPDIAGDEF
--FROM SNCPDIAGDEF
--WHERE DOMDEF = #param1
/*********************************/
SELECT
#PHYPARAMS=[ParamaterValue]
FROM [dbo].[sntbFacilityParamaters] with(nolock)
where [ParamaterTypeId] =
(SELECT TOP 1 [ParamaterTypeId]
FROM [dbo].[sntbParamaterTypeRef] with(nolock)
where ParamaterTypeName ='Physician Specific Packages')
and facid = #param2
IF( ISNULL(#PHYPARAMS ,'N')='N')
BEGIN
SET #param11=''
END
SET NOCOUNT ON;
CREATE TABLE #tempGLT1DET (CODEFROM VARCHAR(32))
INSERT INTO #tempGLT1DET
SELECT A.CODEFROM FROM snlocGLT1DET A with(nolock)
INNER JOIN snlocGLTABLE1 B with(nolock) ON A.GLTABLE1 = B.SYSKEY
WHERE A.CODETYPE IN ('4', '5')
AND NAME = 'AMA HCPCS'
AND (B.EFF_DATE <= #NOW OR B.EFF_DATE='')
AND (B.TRM_DATE >= #NOW OR B.TRM_DATE='')
AND (B.ACTIVATION_DT <= #NOW)
if(#top>300)
BEGIN
SET #top=300
END
IF(ISNULL(#param5,'')='' )
BEGIN
SET #param6=0
END
IF( ISNULL(#param7,'')='')
BEGIN
SET #param8=0
END
SELECT * INTO #TEMPPACKAGECOMPLETE
FROM
(SELECT --TOP(#TOP)
A.SYSKEY,
A.MCOMMORD,
A.SERVTYPE,
A.DESCRIPTION,
isnull(A.some_ver,'9') as some_ver,
A.ER,
A.OUTPATIENT,
A.INPATIENT,
A.DRG,
A.EFF_DATE,
A.TRM_DATE,
A.DOMDEF,
A.FINCLASS,
A.FORMORD,
A.AUDIT,
A.ALTDESC,
A.CODE,
B.TOTALCHARGE,
--null AS PHYSNAME,
A.PHYSNAME,
--NULL AS NPI,
A.NPI,
A.CPPACKAGE_PARAMS,A.PROCCODE,A.HCPCSRATES
--,row_number() over(partition BY A.SYSKEY
-- ORDER BY A.SYSKEY) rn
FROM
(SELECT *
FROM
(SELECT --TOP(#TOP)
CPPACKAGEDEF.SYSKEY,
isnull(CPPACKAGEDEF.some_ver,'9') as some_ver,
CPPACKAGEDEF.MCOMMORD,
CPPACKAGEDEF.SERVTYPE,
CPPACKAGEDEF.DESCRIPTION AS 'DESCRIPTION',
CPPACKAGEDEF.ER,
CPPACKAGEDEF.OUTPATIENT,
CPPACKAGEDEF.INPATIENT,
CPPACKAGEDEF.DRG,
CPPACKAGEDEF.EFF_DATE,
CPPACKAGEDEF.TRM_DATE,
CPPACKAGEDEF.DOMDEF,
CPPACKAGEDEF.FINCLASS,
CPPACKAGEDEF.FORMORD,
CPPACKAGEDEF.AUDIT,
CPPACKAGEDEF.ALTDESC,
REVDET.REVCODE, --REMOVE
P.PROCCODE,REVDET.HCPCSRATES,
CODE = CASE WHEN ISNULL(params.MinCode,'') = '' THEN ''
WHEN params.MinCode = params.MaxCode THEN params.MinCode
ELSE 'Multiple' END,
-- CODE = CASE WHEN
--(SELECT count(1)
-- FROM SNCPPKG_PARAMS_DTLS d with(nolock)
-- WHERE CPPACKAGE_PARAMS = CPPACKAGEDEF.CPPACKAGE_PARAMS
-- AND CODETYPE = 5) > 1 THEN 'Multiple' ELSE ISNULL(
-- (SELECT CODE
-- FROM SNCPPKG_PARAMS_DTLS d with(nolock)
-- WHERE CPPACKAGE_PARAMS = CPPACKAGEDEF.CPPACKAGE_PARAMS
-- AND CODETYPE = 5), '') END,
CPPACKAGEDEF.CPPACKAGE_PARAMS,
ISNULL(SC_TYPE,'R')AS SC_TYPE
FROM SNCPPACKAGEDEF AS CPPACKAGEDEF with(nolock)
LEFT JOIN #SNCPPKG_PARAMS_DTLS AS params ON params.CPPACKAGE_PARAMS = CPPACKAGEDEF.CPPACKAGE_PARAMS
LEFT JOIN #SNCPPACKAGERL REVDET ON REVDET.CPPACKAGEDEF= CPPACKAGEDEF.syskey-- and REVDET.domdef= #param1
--start:rajesh:for diag and proc
left join SNCPPROCDEF p with (nolock) on (P.CPPACKAGEDEF = CPPACKAGEDEF.syskey) and p.domdef= #param1
left join SNCPDIAGDEF d with (nolock) on (d.CPPACKAGEDEF = CPPACKAGEDEF.syskey) and d.domdef= #param1
--LEFT JOIN SNCPPACKAGERL pkgRL ON pkgRL.CPPACKAGEDEF= C.syskey
where
(
((isnull(#param5,'')='') or (d.DIAGCODE like #param5+'%'))
and
((isnull(#param7,'')='') or (p.PROCCODE like #param7+'%'))
)
AND
(
((#param13='9') AND (ISNULL(CPPACKAGEDEF.some_ver,'9')='9')) OR
((#param13='0') AND (ISNULL(CPPACKAGEDEF.some_ver,'9')='0'))
OR
(ISNULL(#param13,'')='')
)
--AND REVDET.
-- AND p.DOMDEF = #param1
--AND d.DOMDEF = #param1
AND
(
ISNULL(#param7,'')=''
OR
(
(#param12='IP' AND ISNULL(#param7,'')<>'')
--AND
--(
--( P.PROCCODE IN
-- ( SELECT DISTINCT DESTCODE FROM snVwCodeXWalk XWALK WHERE XWALK.SOURCECODE = #param10)
--)
--)
)
OR
(
((#param12='OP' OR #param12='ER') AND ISNULL(#param7,'')<>'')
AND
(
REVDET.HCPCSRATES like #param10+'%'
)
)
)
AND
(
(
( (#param5=1 AND #param8=0 )
AND
(d.SEQUENCE=1)
)
--or ISNULL(#param5,'')=''
)
OR
(
((#param8=1 AND #param6=0) AND
(p.SEQUENCE=1) )
--OR ISNULL(#param7,'')=''
)
OR
(
(
(#param5=1 )--AND ISNULL(#param5,'')<>'')
AND (#param8=1)-- AND ISNULL(#param7,'')<>'')
AND (p.SEQUENCE=1 )
AND (d.SEQUENCE=1 )
)
)
OR
(#param5=0 AND #param8=0)
)
--end:rajesh for diag and proc
--where SYSKEY = '126FAQ00249R' and
AND
(
(CPPACKAGEDEF.DESCRIPTION LIKE '%'+#param3+'%')
OR (CPPACKAGEDEF.ALTDESC LIKE '%'+#param3+'%')
OR (ISNULL(#param3,'')='')
)
AND
( (REVDET.REVCODE LIKE #param9+'%') OR (ISNULL(#param9,'')='' ))
AND( (CPPACKAGEDEF.DRG LIKE #param4+'%') OR (ISNULL(#param4,'')='') )
AND
-- ISNULL(CPPACKAGEDEF.SC_TYPE,'R')=
-- CASE WHEN #PHYPARAMS='Y'
-- THEN 'P'
--ELSE
--'R'
--end
(
(#PHYPARAMS='Y' AND CPPACKAGEDEF.SC_TYPE='P' AND ISNULL(#param11,'')<>'' )
OR
(#PHYPARAMS='Y'AND ISNULL(#param11,'')='' )
OR
(#PHYPARAMS='N'AND ISNULL(CPPACKAGEDEF.SC_TYPE,'R')='R' )
)
AND (CPPACKAGEDEF.EFF_DATE <= #NOW OR ISNULL(CPPACKAGEDEF.EFF_DATE,'')='')
AND (CPPACKAGEDEF.TRM_DATE >= #NOW OR ISNULL(CPPACKAGEDEF.TRM_DATE,'')='')
AND CPPACKAGEDEF.DOMDEF=#param1
--AND p.DOMDEF=#param1
--AND d.DOMDEF=#param1
) CPPACKAGEDEF
LEFT JOIN
(SELECT PHYSNAME,
phyPARAMS,
NPI
FROM
(SELECT DISTINCT b.PHYSNAME,
b.NPI,
cp.SYSKEY phyPARAMS,
ROW_NUMBER() OVER (PARTITION BY b.NPI,cp.SYSKEY
ORDER BY b.MDATE DESC) AS rowNum
FROM dbo.BILLPHYS b
INNER JOIN SNCPPACKAGE_PARAMS cp with(nolock) ON cp.NPI = b.NPI
WHERE ISNULL(b.NPI, '') <> '') phy
WHERE phy.rowNum=1) B ON B.phyPARAMS = CPPACKAGEDEF.CPPACKAGE_PARAMS
WHERE (CPPACKAGEDEF.SYSKEY <> ''
AND CPPACKAGEDEF.AUDIT = 'Z')
AND (CPPACKAGEDEF.DOMDEF IN (#param1))
AND (
((CPPACKAGEDEF.INPATIENT = 'Y') AND (#param12='IP'))
OR
((CPPACKAGEDEF.OUTPATIENT = 'Y') AND (ISNULL(#param12,'OP')='OP'))
OR
((#param12='ER' AND CPPACKAGEDEF.OUTPATIENT = 'Y' )AND CONVERT(INT,CPPACKAGEDEF.REVCODE) BETWEEN 450 AND 459)
)
) A
LEFT JOIN
(SELECT SUM(CONVERT(MONEY, LINECHARGE) * UNITS) AS 'TOTALCHARGE', CPPACKAGEDEF FROM
(SELECT LINECHARGE,
UNITS,
CPPACKAGEDEF
FROM #SNCPPACKAGERL with(nolock)) B
GROUP BY CPPACKAGEDEF) B ON A.SYSKEY = B.CPPACKAGEDEF
) A
-- LEFT JOIN SNCPPACKAGERL REVDET ON REVDET.CPPACKAGEDEF= A.syskey AND REVDET.DOMDEF=#param1
WHERE
--rn= 1
--AND
( (A.PHYSNAME LIKE #param11+'%') OR (ISNULL(#param11,'')='' ))
--
--select * from #TEMPPACKAGECOMPLETE
---
--SELECT count(DISTINCT SYSKEY)FROM #TEMPPACKAGE
-- gpant start
Select top (#top) * into #TEMPPACKAGE from (Select *,row_number() over(partition BY SYSKEY
ORDER BY SYSKEY) rn from #TEMPPACKAGECOMPLETE where ((
ISNULL(#param7,'')=''
OR
(
(#param12='IP' AND ISNULL(#param7,'')<>'')
AND
(
( PROCCODE IN
( SELECT DISTINCT DESTCODE FROM snVwCodeXWalk XWALK WHERE XWALK.SOURCECODE = #param10)
)
)
)
OR
(
((#param12='OP' OR #param12='ER') AND ISNULL(#param7,'')<>'')
--AND
--(
-- HCPCSRATES like #param10+'%'
--)
)
) ))t where rn =1
-- --gpant end
SELECT
--count(distinct T.SYSKEY) AS ScSyskey
T.SYSKEY AS ScSyskey,
T.DESCRIPTION AS ScDescription,
T.PHYSNAME AS ScPhysician ,
CASE WHEN ISNULL(#param12 ,'OP')='OP' THEN 'OP'
ELSE
CASE WHEN #param12='IP' THEN 'IP'
ELSE
CASE WHEN #param12='ER' THEN 'ER'
END
END
END ScPatientType,
--'I' AS ScPatientType,
T.DRG AS ScDiagnosis,
T.CODE AS ScPrimaryCdmProcedure ,
CASE WHEN P.DIAG_PRIMARYCODE='Y' THEN P.DIAGCODE ELSE NULL END AS ScPrimaryIcdDiagnosis,
CASE WHEN P.PROC_PRIMARYCODE='Y' THEN P.PROCCODE ELSE NULL END AS ScPrimaryIcdProcedure,
ISNULL(T.TOTALCHARGE, 0) AS ScAmount,
T.MCOMMORD AS ScClaimCount,
C.CODE AS ScCode,
C.CODETYPEDESC AS ScCodeType,
T.DESCRIPTION AS ScCodeDescription,
CAST(C.DATEFROM AS DATETIME) AS ScDateFrom,
CAST(C.DATETO AS DATETIME) As ScDateTo,
REVCODE.UNITS AS CdmUnits,
REVCODE.UNITSORDAYS AS CdmUnitType,
REVCODE.CPT4 AS CdmCode,
REVCODE.MODIFIERS AS CdmModifier,
REVCODE.REVCODE AS CdmRevenueCode,
REVCODE.REVDESC AS CdmDescription,
REVCODE.CHARGECODE AS CdmChargeCode,
REVCODE.LINECHARGE AS CdmPerUnitCharge,
P.DIAGCODE AS IcdDiagCode,
P.DIAG_PRIMARYCODE AS IcdDiagIsPrimary,
P.DIAGDESC AS IcdDiagDescription,
P.PROCCODE AS IcdProcCode,
P.PROC_PRIMARYCODE AS IcdProcIsPrimary,
P.PROCDESCS AS IcdProcDescription,
p.ProcedureSequence,
p.DiagSequence
FROM #TEMPPACKAGE T
LEFT JOIN
(
select distinct x.syskey as CPPACKAGEDEF,
proce.PROCCODE AS PROCCODE,
diag.DIAGCODE AS DIAGCODE,
PROCDESC.PROCDESC AS PROCDESCS ,
DIAGDESC.DIAGDESC AS DIAGDESC,
ISNULL(PROCDESC.ICD_CODE_VERSION,'ICD9Proc') as proccode_version ,
ISNULL(DIAGDESC.ICD_CODE_VERSION,'ICD9Dx') as diagcode_version, --ISNULL(p.DIAGDESC.ICD_CODE_VERSION,'ICD9Dx')
PROCDESC.VALID AS ISPROCVALID,
DIAGDESC.VALID AS ISDIAGVALID,
CASE WHEN PROCE.SEQUENCE =1 THEN 'Y' ELSE 'N' END AS PROC_PRIMARYCODE,
CASE WHEN DIAG.SEQUENCE =1 THEN 'Y' ELSE 'N' END AS DIAG_PRIMARYCODE ,
PROCE.SEQUENCE AS ProcedureSequence,
DIAG.SEQUENCE AS DiagSequence
from
--(
(
select distinct c.syskey as syskey
from snCPPACKAGEDEF C where domdef=#param1
)x
left join SNCPPROCDEF proce on (x.syskey=proce.CPPACKAGEDEF and proce.DOMDEF = #param1)
left join SNCPDIAGDEF diag on (x.syskey=diag.CPPACKAGEDEF and diag.DOMDEF = #param1)
left join SNLOCCP_DTPROC PROCDESC with(nolock) ON (proce.PROCCODE = PROCDESC.PROCCODE and PROCDESC.valid='Y' )
LEFT JOIN SNLOCCP_DTDIAG DIAGDESC with(nolock) ON (diag.DIAGCODE = DIAGDESC.DIAGCODE and DIAGDESC.valid='Y')
) P
ON T.SYSKEY = P.CPPACKAGEDEF
LEFT JOIN
VWCODEDESC AS C ON T.CPPACKAGE_PARAMS = C.CPPACKAGE_PARAMS
LEFT JOIN
(SELECT DISTINCT pkgRL.CPPACKAGEDEF, pkgRL.CHARGECODE, pkgRL.UNITS, pkgRL.UNITSORDAYS, pkgRL.SEQUENCE,
pkgRL.PERRELEVANCE, CAST(ISNULL(pkgRL.MOD1,'') + ','+ ISNULL(pkgRL.MOD2,'') + ','+ ISNULL(pkgRL.MOD3,'')+ ','+ ISNULL(pkgRL.MOD4,'') AS VARCHAR(50)) AS MODIFIERS, pkgRL.UNITWEIGHT,
ISNULL(pkgRL.REVDESC,'Procedure no longer exists!') AS REVDESC, pkgRL.HCPCSRATES,
pkgRL.REVCODE, pkgRL.LINECHARGE, pkgRL.STATCHARGE, pkgRL.CDMCHARGE,
CASE WHEN pkgRL.HCPCSRATES = '' OR pkgRL.HCPCSRATES IN (SELECT CODEFROM FROM #tempGLT1DET) THEN pkgRL.HCPCSRATES ELSE 'Invalid HCPCS Code:' + pkgRL.HCPCSRATES END AS 'CPT4'
FROM #SNCPPACKAGERL pkgRL ) revcode
ON T.SYSKEY = revcode.CPPACKAGEDEF
where
--(ISNULL(p.PROCCODE,'')<>'' OR ISNULL(p.DIAGCODE,'')<>'')
--AND
ISNULL(ISDIAGVALID,'Y')='Y' AND ISNULL(ISPROCVALID,'Y')='Y'
and
(
(
(
(T.some_ver='9' AND ISNULL(p.diagcode_version,'ICD9Dx')='ICD9Dx' )
OR
(T.some_ver='0' AND p.diagcode_version='ICD10CM')
OR
(ISNULL(P.DIAGCODE,'')='')
)
AND
(
(T.some_ver='9' AND ISNULL(p.proccode_version,'ICD9Proc')='ICD9Proc' )
OR
(T.some_ver='0' AND p.proccode_version='ICD10PCS')
OR
(ISNULL(P.PROCCODE,'')='')
)
)
OR
((ISNULL(P.DIAGCODE,'')='')OR(ISNULL(P.PROCCODE,'')='') )
)
ORDER BY CASE
WHEN UPPER(#SORTFIELD) = 'DESCRIPTION' AND
#SORTDIRECTION = 'DESC' THEN T.DESCRIPTION
END DESC,
CASE
WHEN UPPER(#SORTFIELD) = 'DESCRIPTION' AND
#SORTDIRECTION != 'DESC' THEN T.DESCRIPTION
END ASC,
CASE
WHEN UPPER(#SORTFIELD) = 'CHARGECODE' AND
#SORTDIRECTION = 'DESC' THEN
T.SYSKEY
END DESC,
CASE
WHEN UPPER(#SORTFIELD) = 'CHARGECODE' AND
#SORTDIRECTION != 'DESC' THEN
T.SYSKEY
END ASC
END
In the procedure param1 and param2 are mandatory. when I search with the rest of the params, my procedure is giving me average performance(withing 10-12 seconds). But When I search with param10 I am getting the result in 16 minutes which is unacceptable. I have tried to tweak the procedure by changing the where clause positions, implementing temp tables but did not help.
Suggest some ways which can increase the performance with only param10.
Try creating an index on REVDET.HCPCSRATES and then on snVwCodeXWalk.SOURCECODE. Try one first, then the other, then both, and see what effect it has.

Resources