Sql 我想优化这个查询
我有以下表格:Sql 我想优化这个查询,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有以下表格: 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
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
不幸的是,两者都不是最优的。我猜您关心的是性能和查询的执行计划。第二种方法无疑为SQL Server提供了更好的优化计划机会——这仅仅是因为或很难优化
但这并没有考虑到“参数嗅探”。关于这个问题有很多文章(这是一篇合理的文章)
参数嗅探意味着SQL Server在第一次调用存储过程时编译查询。这节省了重新编译查询的开销——如果您有很多“小”查询,这一节省非常重要。但对于更大的查询来说,这是一个愚蠢的交易——因为它没有考虑表上的统计数据
我建议你研究一下有关这方面的文章。您可能会发现第二种解决方案就足够了。您可能会发现,只需添加选项recompile
就足够了。您可能会发现,您希望将查询构造为动态SQL——嘿,您知道它无论如何都会被重新编译。但是你可以做出更明智的决定。 你可以考虑写三个查询来划分你的结果,其中每个查询都处理你的一个或谓词,并结合所有的结果。
在伪代码中:
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
话虽如此,我实际上认为您应该更改数据模型。这是非常有(和非常缓慢)推进与此设置。您可能没有正确规范化数据库。这个问题更适合dbo。DetailsSubType没有子类型。你能解释一下你想达到什么目的吗?例如@subtype为null时,则DetailsSubType.customOR必须为=0