Slow Stored Procedure In ASP.NET But Fast In SSMS - sql

I have stored procedure with runs fast in SQL Management Studio but it is 10 times slower in ASP.NET application. What is the reason of this strange behaviour and idea to fix it ?
This is my Stored Procedure:
Create procedure [dbo].[CRFarmersGet]
#Company NVARCHAR(200) = NULL,
#FName NVARCHAR(50) = NULL,
#SName NVARCHAR(50) = NULL,
#LName NVARCHAR(50) = NULL,
#PID NVARCHAR(50) = NULL,
#RegProvince NVARCHAR(50) = NULL,
#RegCity NVARCHAR(50) = NULL,
#ActCity NVARCHAR(50) = NULL,
#ActCommune NVARCHAR(50) = NULL,
#ActProvince NVARCHAR(50) = NULL,
#SCATTUAct NVARCHAR(50) = NULL,
#Culture NVARCHAR(50) = NULL,
#CultureCode NVARCHAR(50) = NULL,
#Contracts SMALLINT = 0
WITH ENCRYPTION
As
BEGIN
SET #Company = NULLIF(RTRIM(LTRIM(#Company)), '')
SET #FName = NULLIF(RTRIM(LTRIM(#FName)), '')
SET #SName = NULLIF(RTRIM(LTRIM(#SName)), '')
SET #LName = NULLIF(RTRIM(LTRIM(#LName)), '')
SET #PID = NULLIF(RTRIM(LTRIM(#PID)), '')
SET #RegProvince = NULLIF(RTRIM(LTRIM(#RegProvince)), '')
SET #RegCity = NULLIF(RTRIM(LTRIM(#RegCity)), '')
SET #ActCity = NULLIF(RTRIM(LTRIM(#ActCity)), '')
SET #ActCommune = NULLIF(RTRIM(LTRIM(#ActCommune)), '')
SET #ActProvince = NULLIF(RTRIM(LTRIM(#ActProvince)), '')
SET #SCATTUAct = NULLIF(RTRIM(LTRIM(#SCATTUAct)), '')
SET #Culture = NULLIF(RTRIM(LTRIM(#Culture)), '')
SET #CultureCode = NULLIF(RTRIM(LTRIM(#CultureCode)), '')
select
f.[ID]
,f.[PID]
,f.[PIDType]
,f.[DerecognitionDate]
,f.[Company]
,f.[FName]
,f.[SName]
,f.[LName]
,l.ProvinceID as RegProvinceID
,l.Province as RegProvince
,l.CommuneID as RegCommuneID
,l.Commune as RegCommune
,f.[RegCityID]
,l.City as RegCity
,f.[AddrReg]
,f.[Sync]
,f.[D_Modify]
,f.[U_Modify]
,f.[Version]
from CRFarmersT f
join (select CityID, City, c.CommuneID, Commune, m.ProvinceID, Province from CitiesT c join MunicipalitiesT m on c.CommuneID = m.CommuneID join ProvincesT pr on m.ProvinceID = pr.ProvinceID) l on l.CityID = f.RegCityID
LEFT JOIN dbo.CRFarmersDetailsT AS cfdt ON cfdt.FarmerID = f.ID
LEFT JOIN (select CityID, City, c.CommuneID, Commune, m.ProvinceID, Province from CitiesT c join MunicipalitiesT m on c.CommuneID = m.CommuneID join ProvincesT pr on m.ProvinceID = pr.ProvinceID) fdl on fdl.CityID = cfdt.ActCityID
LEFT JOIN dbo.CRCultures AS cc ON cc.ID = cfdt.CultureID
LEFT JOIN dbo.CRContracts AS cc2 ON cc2.FarmerDetailID = cfdt.ID
where
(f.Company like + '%' + rtrim(ltrim(#Company)) + '%' OR #Company IS NULL)
AND (f.fName like + '%' + rtrim(ltrim(#FName)) + '%' OR #FName IS NULL)
AND (f.SName like + '%' + rtrim(ltrim(#SName)) + '%' OR #SName IS NULL)
AND (f.LName like + '%' + rtrim(ltrim(#LName)) + '%' OR #LName IS NULL)
AND (f.PID like + '%' + rtrim(ltrim(#PID)) + '%' OR #PID IS NULL)
AND (l.ProvinceID like + '%' + rtrim(ltrim(#RegProvince)) + '%' OR #RegProvince IS NULL)
AND (l.City like + '%' + rtrim(ltrim(#RegCity)) + '%' OR #RegCity IS NULL)
AND (fdl.City like + '%' + rtrim(ltrim(#ActCity)) + '%' OR #ActCity IS NULL)
AND (fdl.Commune like + '%' + rtrim(ltrim(#ActCommune)) + '%' OR #ActCommune IS NULL)
AND (fdl.Province like + '%' + rtrim(ltrim(#ActProvince)) + '%' OR #ActProvince IS NULL)
AND (cfdt.[SCATTU-Activity] like + '%' + rtrim(ltrim(#SCATTUAct)) + '%' OR #SCATTUAct IS NULL)
AND (cc.Name like + '%' + rtrim(ltrim(#Culture)) + '%' OR #Culture IS NULL)
AND (cc.Code like + '%' + rtrim(ltrim(#CultureCode)) + '%' OR #CultureCode IS NULL)
AND (#Contracts = 1 AND cc2.ID IS NOT NULL OR #Contracts = 0)
AND exists(select 1 from dbo.UserRights('00000000-0000-0000-0000-000000000000') where RightID in (600, 601, 602, 612, 613))
GROUP BY f.[ID]
,f.[PID]
,f.[PIDType]
,f.[DerecognitionDate]
,f.[Company]
,f.[FName]
,f.[SName]
,f.[LName]
,l.ProvinceID
,l.Province
,l.CommuneID
,l.Commune
,f.[RegCityID]
,l.City
,f.[AddrReg]
,f.[Sync]
,f.[D_Modify]
,f.[U_Modify]
,f.[Version]
Order By PID
END
Go

Probably SSMS and ASP.NET are using a different execution plan. One thing to try is to add a With Recompile as in:
Create procedure [dbo].[CRFarmersGet]
#Company NVARCHAR(200) = NULL,
#FName NVARCHAR(50) = NULL,
#SName NVARCHAR(50) = NULL,
#LName NVARCHAR(50) = NULL,
#PID NVARCHAR(50) = NULL,
#RegProvince NVARCHAR(50) = NULL,
#RegCity NVARCHAR(50) = NULL,
#ActCity NVARCHAR(50) = NULL,
#ActCommune NVARCHAR(50) = NULL,
#ActProvince NVARCHAR(50) = NULL,
#SCATTUAct NVARCHAR(50) = NULL,
#Culture NVARCHAR(50) = NULL,
#CultureCode NVARCHAR(50) = NULL,
#Contracts SMALLINT = 0
WITH ENCRYPTION, RECOMPILE
(I am not sure what the syntax is for having both Encryption and Recompile)
Here is a related question and an interesting read

Related

Error in using SELECT to set a variable value in SQL

I have following stored procedure and I have identified the issue with the stored procedure is that using select to set the value of #DeliveryAddress variable and so for all the Letter Requests raised it is only retaining the last value which is in Requests. I tried using SET by explicitly setting each value used in #DeliveryAddresss Calculation but of no use as I ended of getting error that subquery returns multiple rows.
I am unable to understand what shall I change in this SP, so that for each value in #Requests, a different #deliveryAddress value is set and used for insertion in LetterRequest table. Please help.
Note #WorkFlowAcct is a temp table having around 10 unique AccountIds and for each account we have atleast one debtorid.
ALTER PROCEDURE [dbo].[WorkFlow_Action_RequestLetterPref]
AS
DECLARE #LetterID INTEGER;
DECLARE #LetterType CHAR(3);
DECLARE #LetterDescription VARCHAR(50);
DECLARE #JobName VARCHAR(256);
DECLARE #DateCreated DATETIME;
DECLARE #DeliveryMethod VARCHAR(7);
DECLARE #DeliveryAddress VARCHAR(1023);
SELECT #LetterID = [LetterID],
#LetterType = CASE
WHEN [type] IN ('SIF', 'PIF', 'PPS', 'PDC', 'ATT', 'CUS') THEN [type]
ELSE 'DUN'
END,
#LetterDescription = ISNULL([Description], ''),
FROM [dbo].[letter]
WHERE [code] = #LetterCode;
DECLARE #Requests TABLE (
[AccountID] INTEGER NOT NULL,
[DebtorID] INTEGER NOT NULL,
[Seq] INTEGER NOT NULL,
[ErrorMessage] VARCHAR(500) NULL
);
IF #PrimaryDebtor = 1 OR #LetterType IN ('CUS', 'ATT') BEGIN
INSERT INTO #Requests ([AccountID], [DebtorID], [Seq])
SELECT DISTINCT [master].[number] AS [AccountID],
[Debtors].[DebtorID] AS [DebtorID],
[Debtors].[Seq] AS [Seq],
FROM #WorkFlowAcct AS [WorkFlowAcct]
INNER JOIN [dbo].[master] WITH (NOLOCK)
ON [WorkFlowAcct].[AccountID] = [master].[number]
INNER JOIN [dbo].[customer] WITH (NOLOCK)
ON [master].[customer] = [customer].[customer]
INNER JOIN [dbo].[Debtors] WITH (NOLOCK)
ON [master].[number] = [Debtors].[number]
AND [Debtors].[Seq] = [master].[PSeq]
LEFT OUTER JOIN [dbo].[DebtorAttorneys]
ON [Debtors].[DebtorID] = [DebtorAttorneys].[DebtorID];
END;
DECLARE #Street1 VARCHAR(512);
DECLARE #Street2 VARCHAR(512);
DECLARE #City VARCHAR(512);
DECLARE #Country VARCHAR(512);
DECLARE #Zip VARCHAR(512);
IF #Pref = 'Letter'
BEGIN
SET #DeliveryMethod = 'Letter';
SELECT #DeliveryAddress = [Street1] + ' ' + [Street2] + ' ' + [City] + ' ' + [Zipcode] + ' ' + [Country], #Street1 = [Street1], #Street2 = [Street2], #City = [City], #Country = [Country], #Zip = [ZipCode] FROM [Debtors] inner join #Requests AS Requests on [Debtors].[DebtorID] = Requests.[DebtorID] AND [Street1] IS NOT NULL;
IF #Street2 IS NULL
BEGIN
SET #DeliveryAddress = #Street1 + ' ' + #City + ' ' + #Zip + ' ' + #Country;
END
END
SET #DateCreated = GETDATE();
SET #JobName = 'WorkFlow_' + CAST(NEWID() AS CHAR(36)) + CAST(NEWID() AS CHAR(36)) + CAST(NEWID() AS CHAR(36)) + CONVERT(VARCHAR(50), GETDATE(), 126);
BEGIN TRANSACTION;
--Updated params for current Letter Request Table
INSERT INTO [dbo].[LetterRequest] ([AccountID], [LetterID], [LetterCode], [DeliveryMethod], [DeliveryAddress])
SELECT [Requests].[AccountID],
[Requests].[CustomerCode],
#LetterID AS [LetterID],
#LetterCode AS [LetterCode],
#DeliveryMethod AS [DeliveryMethod],
#DeliveryAddress AS [DeliveryAddress]
FROM #Requests AS [Requests]
INNER JOIN #AllowedCustomers AS [AllowedCustomers]
ON [Requests].[CustomerCode] = [AllowedCustomers].[CustomerCode]
WHERE [Requests].[ErrorMessage] IS NULL;
COMMIT TRANSACTION;
RETURN 0;

SQL Server Dynamic where clause query

I am trying to create a dynamic query I just to do with linq
from a in Customers
where (string.IsNullOrEmpty(name)? true : a.FirstName == name) && (string.IsNullOrEmpty(last)? true : a.LastName == last)
select a;
but now I need to do in on Stored Procedure and I don't want to concatenate for security reason and performance. The most close example I found is this query
declare #Name as varchar(100)
declare #GroupName as varchar(100)
set #Name = ''
set #GroupName = 'Manufacturing'
SELECT TOP (1000) [DepartmentID]
,[Name]
,[GroupName]
,[ModifiedDate]
FROM [AdventureWorks2017].[HumanResources].[Department]
where ([Name] = case
when #Name is null or #Name = '' then null
else #Name
end
)
and
(
[GroupName] = case
when #GroupName is null or #GroupName = '' then null
else #GroupName
end
)
This almost works. I think this should be the answer but the where clause fails for obvious reason.
I would like the where clause could produce '1=1' if the param "Name" or "GroupName" is null
example
#Name = "Somename"
#GroupName = null
where (Name = #Name) and (1 = 1)
--or
#Name = null
#GroupName = "Somegruopname"
where (1 = 1) and (GroupName = #GroupName)
--
#Name = null
#GroupName = null
where (1 = 1) and (1 = 1)
You want it to succeed if the variable is null or empty or a match, so I would just write that in your stored procedure.
WHERE (#FirstName is null OR #FirstName = '' OR [FirstName] = #FirstName)
AND (#LastName is null OR #LastName = '' OR [LastName] = #LastName)
Please try this:
declare #Name as varchar(100)
declare #GroupName as varchar(100) = 'Manufacturing'
set #Name = LTRIM(RTRIM(#Name))
set #GroupName = 'Manufacturing'
SELECT TOP (1000) [DepartmentID]
,[Name]
,[GroupName]
,[ModifiedDate]
FROM [AdventureWorks2017].[HumanResources].[Department]
where ([Name] = coalesce(#Name,'') = '' OR [Name] = #Name)
and
([GroupName] = coalesce(#GroupName, '') = '' OR [GroupName] = #GroupName)

Append string in where clause in SQL

I have a function in SQL that returns where clause result like this
CREATE FUNCTION dwd.GetSearchCriteria
(
#pValue NVARCHAR(50),
#pCriteriaOption NVARCHAR(3)
)
RETURNS varchar(30)
AS
BEGIN
declare
#WHERE varchar(2000)
IF(#pValue IS NOT NULL)
BEGIN
SET #WHERE = CASE WHEN #pCriteriaOption = 'ST' THEN ' like ''' + #pValue + '%'''
WHEN #pCriteriaOption = 'ET' THEN ' like ''' + '%' + #pValue + ''''
WHEN #pCriteriaOption = 'CT' THEN ' like ' + '''%' + #pValue + '%'''
ELSE ''
END
END
ELSE
BEGIN
SET #WHERE = '= NULL';
END
RETURN #WHERE
END
I have a query that like this which calls this function
declare
#WHERE varchar(2000)
SET #WHERE=dwd.GetSearchCriteria ('A','ET')
SELECT FirstName FROM dwd.[User] WHERE FirstName + #WHERE
My function returns suppose { like %A% } . I need to append it to first name .
It returns this error
An expression of non-boolean type specified in a context where a
condition is expected, near '#WHERE'.
I have along SP like this
ALTER PROCEDURE [dwd].[ADMIN_USER_DETAIL]
(
#pApplicationClientID bigint,
#pUserID bigint,
/* Optional Filters for Dynamic Search*/
#pFirstName nvarchar(50) = NULL,
#pLastName nvarchar(50) = NULL,
#pEmail nvarchar(255) = NULL,
#pLocation nchar(10) = NULL,
#pPhoneNumber nvarchar(50) = NULL,
#pPseudoName nvarchar(500) = NULL,
/*– Pagination Parameters */
#pPageNo INT = 1,
#pPageSize INT = 10,
/*– Sorting Parameters */
#pSortColumn nvarchar(50) = 'FirstName',
#pSortOrder nvarchar(4)='ASC',
#pTotalCount int output
)
AS
BEGIN
/*–Declaring Local Variables corresponding to parameters for modification */
DECLARE
#lFirstName nvarchar(50),
#lLastName nvarchar(50),
#lEmail nvarchar(255),
#lLocation nchar(10),
#lPhoneNumber nvarchar(50),
#lPseudoName nvarchar(500),
#lPageNbr INT,
#lPageSize INT,
#lSortCol NVARCHAR(50),
#lFirstRec INT,
#lLastRec INT,
#lTotalRows INT,
#TotalCount INT
/*Setting Local Variables*/
SET #lFirstName = LTRIM(RTRIM(#pFirstName))
SET #lLastName = LTRIM(RTRIM(#pLastName))
SET #lEmail = LTRIM(RTRIM(#pEmail))
SET #lLocation = LTRIM(RTRIM(#pLocation))
SET #lPhoneNumber = LTRIM(RTRIM(#pPhoneNumber))
SET #lPseudoName = LTRIM(RTRIM(#pPseudoName))
SET #lPageNbr = #pPageNo
SET #lPageSize = #pPageSize
SET #lSortCol = LTRIM(RTRIM(#pSortColumn))
SET #lFirstRec = ( #lPageNbr - 1 ) * #lPageSize
SET #lLastRec = ( #lPageNbr * #lPageSize + 1 )
SET #lTotalRows = #lFirstRec - #lLastRec + 1
; WITH User_Results
AS (
SELECT ROW_NUMBER() OVER (ORDER BY
CASE WHEN (#lSortCol = 'FirstName' AND #pSortOrder='ASC')
THEN U1.FirstName
END ASC,
CASE WHEN (#lSortCol = 'FirstName' AND #pSortOrder='DESC')
THEN U1.FirstName
END DESC,
CASE WHEN (#lSortCol = 'LastName' AND #pSortOrder='ASC')
THEN U1.LastName
END ASC,
CASE WHEN #lSortCol = 'LastName' AND #pSortOrder='DESC'
THEN U1.LastName
END DESC,
CASE WHEN #lSortCol = 'Email' AND #pSortOrder='ASC'
THEN U1.Email
END ASC,
CASE WHEN #lSortCol = 'Email' AND #pSortOrder='DESC'
THEN U1.Email
END DESC,
CASE WHEN #lSortCol = 'Location' AND #pSortOrder='ASC'
THEN U1.LocationID
END ASC,
CASE WHEN #lSortCol = 'Location' AND #pSortOrder='DESC'
THEN U1.LocationID
END DESC,
CASE WHEN #lSortCol = 'PhoneNumber' AND #pSortOrder='ASC'
THEN U1.PhoneNumber
END ASC,
CASE WHEN #lSortCol = 'PhoneNumber' AND #pSortOrder='DESC'
THEN U1.PhoneNumber
END DESC,
CASE WHEN #lSortCol = 'PseudoName' AND #pSortOrder='ASC'
THEN U1.PseudoName
END ASC,
CASE WHEN #lSortCol = 'PseudoName' AND #pSortOrder='DESC'
THEN U1.PseudoName
END DESC
) AS ROWNUM,
Count(*) over () AS TotalCount,
U1.ID,
U1.FirstName,
U1.LastName,
U1.Email,
DPD.Value as Location,
U1.PhoneNumber,
U2.FirstName+' '+U2.LastName as ReportTo,
U1.PseudoName,
U1.IsActive,
US.ID AS SId,
US.SkillID AS SkillId,
UR.ID AS RId,
UR.RoleID AS RoleId,
U1.Created,
U1.Deleted
FROM dwd.[User] U1 with (nolock)
INNER JOIN dwd.[User] U2 with (nolock) ON U2.ID=U1.ReportTo
INNER JOIN dwd.[DomainParameterDetail] DPD with (nolock) ON DPD.ID=U1.LocationID
INNER JOIN dwd.[UserSkill] US WITH(NOLOCK) ON U1.ID = US.UserID
INNER JOIN dwd.[UserRole] UR WITH(NOLOCK) ON U1.ID = UR.UserID
WHERE
(#lFirstName IS NULL OR U1.FirstName = #lFirstName)
AND(#lLastName IS NULL OR U1.LastName LIKE '%' + #lLastName + '%')
AND(#lEmail IS NULL OR U1.Email LIKE '%' + #lEmail + '%')
AND (#lLocation IS NULL OR U1.LocationID LIKE '%' + #lLocation + '%')
AND (#lPhoneNumber IS NULL OR U1.PhoneNumber = #lPhoneNumber)
AND (#lPseudoName IS NULL OR U1.PseudoName LIKE '%' +#lPseudoName+ '%')
AND U1.IsActive=1 AND U1.Deleted=0 AND U1.ApplicationClientID=#pApplicationClientID
AND U1.ID<>1
)
SELECT
TotalCount,
ROWNUM,
ID,
FirstName,
LastName,
Email,
Location,
PhoneNumber,
ReportTo,
PseudoName,
IsActive,
S
Id,
SkillId,
RId,
RoleId,
Created,
Deleted
FROM User_Results AS USER_GET_RESULT
WHERE
ROWNUM > #lFirstRec
AND ROWNUM < #lLastRec
ORDER BY ROWNUM ASC
Select #TotalCount = Count(*) from dwd.[User]
WHERE IsActive=1 AND Deleted=0 AND ID<>1
Set #pTotalCount = #TotalCount
END
SO I have to get this donw in where clause of SP.
This is a bit long for a comment.
You can only do what you want using dynamic SQL. But, that seems entirely unnecessary, because all the comparisons use LIKE. So, it is better to write the function as:
CREATE FUNCTION dwd.GetSearchCriteria (
#pValue NVARCHAR(50),
#pCriteriaOption NVARCHAR(3)
)
RETURNS varchar(2000)
AS
BEGIN
declare #LIKEPATTERN varchar(2000) ;
SET #LIKEPATTERN = (CASE WHEN #PValue IS NULL THEN ''''''
WHEN #pCriteriaOption = 'ST' THEN '''' + #pValue + '%'''
WHEN #pCriteriaOption = 'ET' THEN '''' + '%' + #pValue + ''''
WHEN #pCriteriaOption = 'CT' THEN '''%' + #pValue + '%'''
ELSE ''''''
END)
RETURN #LIKEPATTERN
END ;
Note: Using an IF and CASE is redundant. The logic can be combined into a single expression. I also think return types should match the type of the variable being returned.
Then you can express the call as:
DECLARE #LIKEPATTERN varchar(2000);
SET #LIKEPATTERN = dwd.GetSearchCriteria('A','ET');
SELECT FirstName FROM dwd.[User] WHERE FirstName LIKE #LIKEPATTERN;

How to optimize SQL query performance using Row_Number() to operate on millions of records in SQL Server?

In my project, i am using the following query with paging mechanism using Row_Number() in SQL Server 2005 to fetch the records from database containing millions of records. When i execute this query it is taking almost 1:25+ seconds to fetch the results, i am unable to figure out where am i going wrong ? How can we optimize this query to bring the expected results in quick possible time, displaying n records on first page and fetching respective records as paging operation proceeds ?
This is how we create table:
CREATE TABLE [iftable] (
[sid] [float] DEFAULT (0) NOT NULL ,
[mid] [float] DEFAULT (0) NOT NULL ,
[bid] [float] DEFAULT (0) NOT NULL ,
[fid] [float] DEFAULT (0) NOT NULL ,
[fsid] [float] DEFAULT (0) NOT NULL ,
[ftep] [float] DEFAULT (0) NOT NULL ,
[mtid] [float] DEFAULT (0) NOT NULL ,
[mstr] [varchar] (1000) DEFAULT (' ') NOT NULL ,
[urblb] [image] NULL ,
[urcode] [float] DEFAULT (0) NOT NULL ,
[cdate] [datetime] DEFAULT (getdate()) NOT NULL ,
[ctime] [char] (9) DEFAULT (' ') NOT NULL ,
[olevel] [float] DEFAULT (0) NOT NULL,
[cat] [varchar](30) DEFAULT (' ') NOT NULL,
[ukey1] [varchar](30) DEFAULT (' ') NOT NULL,
[ukey2] [varchar](30) DEFAULT (' ') NOT NULL,
[vk] [varchar](30) DEFAULT (' ') NOT NULL,
[scode] [float] DEFAULT (0) NOT NULL,
[sty] [float] DEFAULT (0) NOT NULL,
[extnsn] [varchar](10) DEFAULT ('') NOT NULL,
[pkey] [varchar] (30) DEFAULT (' ') NOT NULL,
[bexists] [smallint] DEFAULT (0) NOT NULL
) ON [PRIMARY]
CREATE UNIQUE INDEX [iftablekey01] ON [iftable]([pkey], [sid], [mid]) ON [PRIMARY]
GO
//Select query over the table created
DECLARE #Sid nvarchar(30)
DECLARE #Bid nvarchar(30)
DECLARE #Fid nvarchar(30)
DECLARE #Stid nvarchar(30)
DECLARE #QFid nvarchar(30)
DECLARE #FromDate nvarchar(30)
DECLARE #ToDate nvarchar(30)
DECLARE #RFID nvarchar(30)
DECLARE #FRID nvarchar(30)
DECLARE #FsID nvarchar(30)
DECLARE #Exclude nvarchar(MAX)
DECLARE #ExecuteDSQL nvarchar(MAX)
--Here below all the values will be coming from different variables like #QFid = 'VarQfid'
SET #Sid = '' IF(#Sid = '*') SET #Sid = 'ALL'
SET #Bid = '' IF(#Bid = '*') SET #Bid = 'ALL'
SET #Fid = '' IF(#Fid = '*') SET #Fid = 'ALL'
SET #Stid = '' IF(#Stid = '*') SET #Stid = 'ALL'
SET #QFid = 'ALL'
SET #FromDate = ''
SET #ToDate = ''
SET #RFID = ''
SET #FRID = ''
SET #FsID = ''
SET #Exclude = '' IF(#Exclude = '') SET #Exclude = '100'
SET #ExecuteDSQL = 'SELECT * FROM ( SELECT *, Row_Number() over(order by cdate desc,ctime desc,mid desc) as rowNum from iftable where pkey=''ABC'''
+
' AND (cdate BETWEEN (CASE WHEN '''+#FromDate+''' =''0'' THEN ''1970-01-01'' WHEN '''+#FromDate+''' = '''' THEN ''1970-01-01'' ELSE ''ValueCameFromVariable'' END) AND (CASE WHEN '''+#ToDate+''' = ''0'' THEN ''5000-01-01'' WHEN '''+#ToDate+''' = '''' THEN ''5000-01-01'' ELSE ''ValueCameFromVariable'' END)) '
+
' AND (('''+#QFid+''' = ''ALL'' AND mtid IN (select mtid FROM iftable)) OR ('''+#QFid+''' = ''Err'' AND mtid IN(9,15)) OR ('''+#QFid+''' = ''CLog'' AND mtid IN(9,15,14,50,56))) '
+
' AND sid = (CASE WHEN '''+#Sid+''' = ''ALL'' THEN sid WHEN '''+#Sid+''' = '''' THEN sid ELSE '''+#Sid+''' END) '
+
' AND bid = (CASE WHEN '''+#Bid+''' = ''ALL'' THEN bid WHEN '''+#Bid+''' = '''' THEN bid ELSE '''+#Bid+''' END) '
+
' AND fid = (CASE WHEN '''+#Fid+''' = ''ALL'' THEN fid WHEN '''+#Fid+''' = '''' THEN fid ELSE '''+#Fid+''' END) '
+
' AND stid = (CASE WHEN '''+#Stid+''' = ''ALL'' THEN stid WHEN '''+#Stid+''' = '''' THEN stid ELSE '''+#Stid+''' END)'
+
' AND rfid = (CASE WHEN '''+#RFID+''' = ''0'' THEN rfid WHEN '''+#RFID+''' = '''' THEN rfid ELSE '''+#RFID+''' END) '
+
' AND frid = (CASE WHEN '''+#FRID+''' = ''0'' THEN frid WHEN '''+#FRID+''' = '''' THEN frid ELSE '''+#FRID+''' END) '
+
' AND fsid = (CASE WHEN '''+#FsID+''' = ''0'' THEN fsid WHEN '''+#FsID+''' = '''' THEN fsid ELSE '''+#FsID+''' END)'
+
' AND mtid NOT IN ('+#Exclude+')) AS newTable WHERE newTable.RowNum BETWEEN ''1'' AND ''50'''
exec sp_executesql #ExecuteDSQL
The problem with your Query is you are sorting by cdate desc,ctime desc,mid
but you dont have indexes by all the columns your are using to sort.
You should create this index to improve your query:
CREATE CLUSTERED INDEX [_dta_index_iftable_c_8_205243786__K11D_K12D_K2D] ON [dbo].[iftable]
(
[cdate] DESC,
[ctime] DESC,
[mid] DESC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]

Use If between the where clause

I don't know how exactly I should frame my Question as even I don't know what exactly I have to search. May be this is the best place to put my question. I want to use If condition in where clause this can be done using case but my problem is I don't want to use it after a column name instead I want to avoid entire execution of that column. You can understand it by going through my procedure in the last I have commented, So I want to achieve something like that as I want to write the same procedure again for that condition which i think can be achievable by doing something like that. I searched on internet what I got is to use case in where which doesn't satisfy my purpose. Please look the last lines to understand the problem. Thanx
USE [overseascrm]
GO
/****** Object: StoredProcedure [dbo].[candidatesearch] Script Date: 05-07-2014 00:48:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[candidatesearch]
#candidate_id varchar(50),
#firstname varchar(50),
#lastname varchar(50),
#emailid_1 varchar(100),
#mobile_1 varchar(20),
#from varchar(50),
#to varchar(50),
#agentid varchar(50),
#passportno varchar(50),
#profession int,
#isactive bit
as
begin
DECLARE #candidateid_var varchar(50)
DECLARE #firstname_var varchar(50)
DECLARE #lastname_var varchar(50)
DECLARE #emailid1_var varchar(100)
DECLARE #mobile_1_var varchar(20)
DECLARE #agentid_var varchar(50)
IF(#agentid = '')
begin
SET #agentid_var = '%'
END ELSE BEGIN
SET #agentid_var = #agentid
END
IF (#candidate_id = '') BEGIN
SET #candidateid_var = '%'
END ELSE BEGIN
SET #candidateid_var = #candidate_id
END
IF (#firstname = '') BEGIN
SET #firstname_var = '%'
END ELSE BEGIN
SET #firstname_var = #firstname
END
IF (#lastname = '') BEGIN
SET #lastname_var = '%'
END ELSE BEGIN
SET #lastname_var = #lastname
END
IF (#emailid_1 = '') BEGIN
SET #emailid1_var = '%'
END ELSE BEGIN
SET #emailid1_var = #emailid_1
END
IF (#mobile_1 = '') BEGIN
SET #mobile_1_var = '%'
END ELSE BEGIN
SET #mobile_1_var = #mobile_1
END
IF (#from = '') BEGIN
SELECT
*
FROM candidate C
LEFT JOIN candidate_profession_map CM
ON C.candidate_id = CM.candidate_id
LEFT JOIN passport_details PD
ON C.candidate_id = PD.candidate_id
WHERE C.candidate_id LIKE '' + #candidateid_var + '%'
AND firstname LIKE '' + #firstname_var + '%'
AND lastname LIKE '' + #lastname_var + '%'
AND emailid_1 LIKE '' + #emailid1_var + '%'
AND mobile_1 LIKE '' + #mobile_1_var + '%'
AND agent_id LIKE '' + #agentid_var + '%'
AND CM.profession_id = #profession
AND C.isactive = #isactive
AND PD.passport_no = #passportno
END ELSE BEGIN
SELECT
*
FROM candidate C
LEFT JOIN candidate_profession_map CM
ON C.candidate_id = CM.candidate_id
LEFT JOIN passport_details PD
ON C.candidate_id = PD.candidate_id
WHERE C.candidate_id LIKE '' + #candidateid_var + '%'
AND firstname LIKE '' + #firstname_var + '%'
AND lastname LIKE '' + #lastname_var + '%'
AND emailid_1 LIKE '' + #emailid1_var + '%'
AND mobile_1 LIKE '' + #mobile_1_var + '%'
AND agent_id LIKE '' + #agentid_var + '%'
AND C.addedon BETWEEN CONVERT(DATETIME, #from, 103) AND CONVERT(DATETIME, #to, 103)
--IF (#profession <> 0)BEGIN
--AND CM.profession_id = #profession
--END
AND C.isactive = #isactive
OR PD.passport_no = #passportno
END
END
You could use dynamic sql execution where you create your select statement as varchar to your liking, executing it at the end using sp_executesql
http://msdn.microsoft.com/en-us/library/ms188001.aspx
ALTER procedure [dbo].[candidatesearch]
#candidate_id varchar(50),
#firstname varchar(50),
#lastname varchar(50),
#emailid_1 varchar(100),
#mobile_1 varchar(20),
#from varchar(50),
#to varchar(50),
#agentid varchar(50),
#passportno varchar(50),
#profession int,
#isactive bit
AS Begin
SELECT *
FROM candidate C
LEFT JOIN candidate_profession_map CM ON C.candidate_id = CM.candidate_id
LEFT JOIN passport_details PD ON C.candidate_id = PD.candidate_id
WHERE (#candidateid='' or C.candidate_id LIKE #candidateid + '%')
AND (#firstname = '' or firstname LIKE #firstname + '%')
AND (#lastname = '' or lastname LIKE #lastname + '%')
AND (#emailid_1='' or emailid_1 LIKE #emailid1 + '%')
AND (#mobile_1 = '' or mobile_1 LIKE #mobile_1 + '%')
AND (#agentid='' agent_id LIKE #agentid + '%')
AND C.isactive = #isactive
And ((#from=''
AND CM.profession_id = #profession
AND PD.passport_no = #passportno)
or (#from<>''
And C.addedon BETWEEN CONVERT(DATETIME, #from, 103) AND CONVERT(DATETIME, #to, 103)
OR PD.passport_no = #passportno)
End