我使用此条件作为where子句的一部分:exists (select * from PRPB PB where PA.mid = PB.mid and (@inpo is null or PB.inpo = @inpo)) order by price
。
在测试非null的@inpo值时,我注意到当我改为使用这个条件时,查询运行得更快:exists (select * from PRPB PB where PA.mid = PB.mid and (PB.inpo = @inpo)) order by price
。这导致一个不可忽略的速度差异表明我将被迫使用if语句的两个单独的查询,以决定是否过滤掉@inpo。这对我来说是件坏事,因为它意味着很多代码重复。
我尝试过的事情:
我的目标是让它在没有我的查询的两个副本的情况下更快地执行此检查。
这可能吗?如果没有,为什么不呢?如果是这样,怎么样?
注意:另请参阅第二个相关问题here。
答案 0 :(得分:1)
要在不牺牲性能损失的情况下重用代码,您可以创建视图或创建内联UDF。两者都是由优化器扩展的宏。例如,而不是以下代码重复:
CREATE PROCEDURE MyProc
@i1 INT,
@inpo INT
AS
BEGIN
IF @inpo IS NULL BEGIN
SELECT a,b,c
FROM dbo.YourTable
WHERE i1 = @i1
ORDER BY c;
END ELSE BEGIN
SELECT a,b,c
FROM dbo.YourTable
WHERE i1 = @i1
AND inpo = @inpo
ORDER BY c;
END
END
将查询包装在内联udf中并重用它:
CREATE FUNCTION dbo.ReuseMyQuery(@i1 INT)
RETURNS TABLE AS RETURN(
SELECT a,b,c, inpo FROM dbo.YourTable WHERE i1 = @i1
)
GO
ALTER PROCEDURE MyProc
@i1 INT,
@inpo INT
AS
BEGIN
IF @inpo IS NULL BEGIN
SELECT a,b,c
FROM dbo.ReuseMyQuery(@i1)
ORDER BY c;
END ELSE BEGIN
SELECT a,b,c
FROM dbo.ReuseMyQuery(@i1)
WHERE inpo = @inpo
ORDER BY c;
END
END
答案 1 :(得分:0)
如果您尝试这样做会怎样:
exists (select * from PRPB PB where PA.mid = PB.mid and PB.inpo = ISNULL(@inpo, PB.inpo)) order by price
当@inpo为NULL时,ISNULL函数将使它返回第二个参数,并返回PB.inpo,然后该等式将始终评估为true,这与您的条件匹配。