我有下表:
dbo.Details
Name Type SubType SerialNumber
D_01 TxA STxA1 4
D_02 TxB STxB2 3
D_03 TxC STxC1 2
D_04 TxD STxD1 7
D_05 TxD STxD1 1
D_06 TxD STxD1 9
dbo.DetailsType
Code Name
TxA A
TxB B
TxC C
...
dbo.DetailsSubType
Code Type Name CustomOR
STxA1 TxA A1 1
STxA2 TxA A2 0
STxB1 TxB B1 1
STxB2 TxB B2 0
STxC1 TxC C1 1
STxC2 TxC C2 0
STxD TxD D1 1
我想知道哪种查询(A或B)最适合您,请解释一下:
查询A
CREATE PROCEDURE XXX
(
@type nvarchar(10),
@subType nvarchar(10) = null
)
AS
BEGIN
declare @custom bit = 0;
if (@subType is not null)
begin
select @custom = CustomOR from dbo.DetailsSubType where SubType = @subType
end
select
DTST.SubType,
DT.SerialNumber
from dbo.Details as DT
left join DetailsSubType as DTST
on DT.SubType = DTST.Code
where
DT.Type = @type
and
(
@subType is null or
(@custom = 0 and DTST.CustomOR= 0) or
(@custom = 1 and DT.SubType = @subType)
)
END
查询B
declare @custom bit = 0;
if (@subType is not null)
begin
select @custom = CustomOR from dbo.DetailsSubType where SubType = @subType
end
if (@custom = 0)
begin
select
DTST.SubType,
DT.SerialNumber
from dbo.Details as DT
left join DetailsSubType as DTST
on DT.SubType = DTST.Code
where
DT.Type = @type
and
DTST.CustomOR = 0
end
else
begin
select
DTST.SubType,
DT.SerialNumber
from dbo.Details as DT
left join DetailsSubType as DTST
on DT.SubType = DTST.Code
where
DT.Type = @type
and
(DTST.CustomOR = 1 and DT.SubType = @subType)
end
答案 0 :(得分:0)
不幸的是,两者都不是最佳选择。我猜您担心的问题与查询的性能和执行计划有关。第二种方法肯定为SQL Server提供了优化计划的更好机会-仅仅是因为OR
确实很难优化。
但是,这没有考虑“参数嗅探”。关于该主题的文章很多(here是合理的文章。)
参数嗅探意味着SQL Server在第一次调用存储过程时会编译查询。这样可以节省重新编译查询的开销-如果您有很多“小型”查询,这一点很重要。但是,对于较大的查询,傻瓜会讨价还价-因为它没有考虑表的统计信息。
我建议您调查有关此的文章。您可能会发现第二种解决方案已足够。您可能会发现仅添加option recompile
就足够了。您可能会发现您希望将查询构造为动态SQL –嘿,您知道无论如何它将被重新编译。但是您将能够做出更明智的决定。
答案 1 :(得分:0)
您可以考虑编写三个对结果进行分区的查询,其中每个查询恰好处理您的一个OR谓词,然后对所有结果进行UNION。
使用伪代码:
SELECT ... FROM ... WHERE @subType is null
UNION ALL
SELECT ... FROM ... WHERE @subType is NOT null AND DTST.CustomOR = 0 AND @custom = 0
UNION ALL
SELECT ... FROM ... WHERE @subType is NOT null AND DT.SubType = @subType AND @custom = 1
话虽如此,我实际上认为您应该更改数据模型。进行此设置非常(非常慢)。您可能没有正确规范化数据库。