我有一个存储过程,我重复了相同的'not exists'子句。每个选择中的每个“不存在”子句在随后的选择查询中重复,并且“exists”子句在后续选择查询中变为“不存在”。 有没有办法我可以只做一次“非存在”和“存在”并保存这些结果并在整个过程中使用它们?优化的方法是什么? 谢谢!
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_GetCaseType]
@ID numeric(18,0)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @cnt int;
SELECT @cnt = COUNT(*)
FROM tblCase c WITH (NOLOCK)
join tblDepartment cd WITH (NOLOCK) on cd.DepartmentID = c.DepartmentID
join tblType ct WITH (NOLOCK) on ct.TypeID = cd.TypeID
WHERE ct.Type in ('AG', 'PH')
and
not exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('Z', 'W')
and ch.ID = @ID)
and
c.ID = @ID
IF (@cnt > 1)
RETURN 'CATEGORY 1'
SELECT @cnt = COUNT(*)
FROM tblCase c WITH (NOLOCK)
join tblDepartment cd WITH (NOLOCK) on cd.DepartmentID = c.DepartmentID
join tblType ct WITH (NOLOCK) on ct.TypeID = cd.TypeID
WHERE ct.Type in ('AG', 'PH')
and
not exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('Z', 'W')
and ch.ID = @ID)
and
exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('N', 'O')
and ch.ID = @ID)
and
c.ID = @ID
IF (@cnt > 1)
RETURN 'CATEGORY 2'
SELECT @cnt = COUNT(*)
FROM tblCase c WITH (NOLOCK)
join tblDepartment cd WITH (NOLOCK) on cd.DepartmentID = c.DepartmentID
join tblType ct WITH (NOLOCK) on ct.TypeID = cd.TypeID
WHERE ct.Type in ('AG', 'PH')
and
not exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('Z', 'W')
and ch.ID = @ID)
and
not exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('N', 'O')
and ch.ID = @ID)
and
exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('D', 'B')
and ch.ID = @ID)
and
c.ID = @ID
IF (@cnt > 1)
RETURN 'CATEGORY 2'
SELECT @cnt = COUNT(*)
FROM tblCase c WITH (NOLOCK)
join tblDepartment cd WITH (NOLOCK) on cd.DepartmentID = c.DepartmentID
join tblType ct WITH (NOLOCK) on ct.TypeID = cd.TypeID
WHERE ct.Type in ('AG', 'PH')
and
not exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('Z', 'W')
and ch.ID = @ID)
and
not exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('N', 'O')
and ch.ID = @ID)
and
not exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('D', 'B')
and ch.ID = @ID)
and
exists (SELECT * FROM tblCharge ch WITH (NOLOCK)
join tblAction ca WITH (NOLOCK) on ch.ActionID = ca.ActionID
WHERE ca.Code in ('A', 'C')
and ch.ID = @ID)
and
c.ID = @ID
IF (@cnt > 1)
RETURN 'CATEGORY 2'
END
答案 0 :(得分:1)
如果它们是相同的并且它们不是相关的子查询,那么您可以在存储过程开始时将结果保存在变量中,然后在其余查询中使用该变量:
DECLARE
@zw_exists BIT = 0
IF EXISTS (SELECT * FROM ... WHERE Code IN ('Z', 'W') AND CH.ID = @ID)
@zw_exists = 1
对每种类型的查询执行相同操作,然后在其他查询中使用该变量。
答案 1 :(得分:1)
尝试将exists和non存在结合到一个查询中,并且只返回top 1
。这样,您可以最小化SELECT
子句中每WHERE
个语句返回的行数。还为您的proc添加了SET NOCOUNT ON;
,这是一种快速简便的方法,可以提升性能:
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
ALTER PROCEDURE [dbo].[sp_GetCaseType] @ID NUMERIC(18, 0)
AS
SET NOCOUNT ON;
BEGIN
SET NOCOUNT ON;
DECLARE @cnt INT;
SELECT @cnt = COUNT(*)
FROM tblCase c WITH (NOLOCK)
JOIN tblDepartment cd WITH (NOLOCK) ON cd.DepartmentID = c.DepartmentID
JOIN tblType ct WITH (NOLOCK) ON ct.TypeID = cd.TypeID
WHERE ct.Type IN('AG', 'PH')
AND NOT EXISTS
(SELECT *
FROM tblCharge ch WITH (NOLOCK)
JOIN tblAction ca WITH (NOLOCK) ON ch.ActionID = ca.ActionID
WHERE ca.Code IN('Z', 'W')
AND ch.ID = @ID)
AND c.ID = @ID;
IF(@cnt > 1)
RETURN 'CATEGORY 1';
SELECT @cnt = COUNT(*)
FROM tblCase c WITH (NOLOCK)
JOIN tblDepartment cd WITH (NOLOCK) ON cd.DepartmentID = c.DepartmentID
JOIN tblType ct WITH (NOLOCK) ON ct.TypeID = cd.TypeID
WHERE ct.Type IN('AG', 'PH')
AND EXISTS
(SELECT TOP 1 1
FROM tblCharge ch WITH (NOLOCK)
JOIN tblAction ca WITH (NOLOCK) ON ch.ActionID = ca.ActionID
WHERE ca.Code NOT IN('Z', 'W')
AND ca.Code IN('N', 'O')
AND ch.ID = @ID)
AND c.ID = @ID;
IF(@cnt > 1)
RETURN 'CATEGORY 2';
SELECT @cnt = COUNT(*)
FROM tblCase c WITH (NOLOCK)
JOIN tblDepartment cd WITH (NOLOCK) ON cd.DepartmentID = c.DepartmentID
JOIN tblType ct WITH (NOLOCK) ON ct.TypeID = cd.TypeID
WHERE ct.Type IN('AG', 'PH')
AND EXISTS
(SELECT TOP 1 1
FROM tblCharge ch WITH (NOLOCK)
JOIN tblAction ca WITH (NOLOCK) ON ch.ActionID = ca.ActionID
WHERE ca.Code NOT IN('Z', 'W', 'N', 'O')
AND ca.Code IN('D', 'B')
AND ch.ID = @ID)
AND c.ID = @ID;
IF(@cnt > 1)
RETURN 'CATEGORY 2';
SELECT @cnt = COUNT(*)
FROM tblCase c WITH (NOLOCK)
JOIN tblDepartment cd WITH (NOLOCK) ON cd.DepartmentID = c.DepartmentID
JOIN tblType ct WITH (NOLOCK) ON ct.TypeID = cd.TypeID
WHERE ct.Type IN('AG', 'PH')
AND EXISTS
(SELECT TOP 1 1
FROM tblCharge ch WITH (NOLOCK)
JOIN tblAction ca WITH (NOLOCK) ON ch.ActionID = ca.ActionID
WHERE ca.Code NOT IN('Z', 'W', 'N', 'O', 'D', 'B')
AND ca.Code IN('A', 'C')
AND ch.ID = @ID)
AND c.ID = @ID;
IF(@cnt > 1)
RETURN 'CATEGORY 2';
END;