提问人:SkyeBoniwell 提问时间:11/16/2023 最后编辑:XedniSkyeBoniwell 更新时间:11/16/2023 访问量:69
如何降低 CASE 表达式的执行成本?[关闭]
How can I decrease the execution cost of my CASE expressions? [closed]
问:
我的查询中有这个CASE表达式:
CASE el.faunaType
WHEN 2 THEN 'Examine "' + ISNULL((SELECT TOP 1 cellComplex FROM cellList WHERE TRY_CONVERT(NVARCHAR(50), cellID) = TRY_CONVERT(NVARCHAR(50), faunaSource)), '') + '"'
WHEN 9 THEN 'Investigate "' + (SELECT TOP 1 sourceText FROM diseaseSources WHERE TRY_CONVERT(NVARCHAR(50), sourceID) = TRY_CONVERT(NVARCHAR(50), faunaSource)) + '"'
WHEN 15 THEN 'Infection detected "' + (SELECT TOP 1 sourceText FROM diseaseSources WHERE TRY_CONVERT(NVARCHAR(50), sourceID) = TRY_CONVERT(NVARCHAR(50), faunaSource)) + '"'
WHEN 23 THEN 'Forward on "' + (SELECT TOP 1 cellComplex FROM cellList WHERE TRY_CONVERT(NVARCHAR(50), cellID) = TRY_CONVERT(NVARCHAR(50), faunaSource)) + '"'
WHEN 45 THEN 'Traced cell "' + ISNULL((SELECT TOP 1 cellComplex FROM cellList WHERE TRY_CONVERT(NVARCHAR(50), cellID) = TRY_CONVERT(NVARCHAR(50), faunaSource)), '') + '"'
WHEN 77 THEN 'Sampled on "' + (SELECT TOP 1 cellComplex FROM cellList WHERE TRY_CONVERT(NVARCHAR(50), cellID) = TRY_CONVERT(NVARCHAR(50), faunaSource)) + '"<br />[' + faunaMessage + ']'
END As FaunaName
此块对性能造成了巨大的影响。当我查看执行计划时,我看到 和 20% 的成本。diseaseSources
cellList
它正在执行聚簇索引扫描。
我将这两个表的 ID(cellID 和 sourceID)作为主键。
有没有办法降低这个 CASE 语句的性能成本?
答:
2赞
Gavin Clayton
11/16/2023
#1
生成 HTML 的表结构有点猜测,但你最好加入一次,然后改变你处理 SQL 的方式。在您的示例中,您将为每个情况执行唯一的 select 语句,而联接执行一次匹配,然后处理显示。
DECLARE @FT TABLE(faunaType NVARCHAR(100),faunaSource NVARCHAR(50),faunaMessage NVARCHAR(100))
DECLARE @CL TABLE(cellID NVARCHAR(50),cellComplex NVARCHAR(100))
DECLARE @DS TABLE(sourceID NVARCHAR(50),sourceText NVARCHAR(100))
SELECT *,
CASE el.faunaType
WHEN 2 THEN 'Examine "' + ISNULL((SELECT TOP 1 cellComplex FROM @CL WHERE TRY_CONVERT(NVARCHAR(50), cellID) = TRY_CONVERT(NVARCHAR(50), faunaSource)), '') + '"'
WHEN 9 THEN 'Investigate "' + (SELECT TOP 1 sourceText FROM @DS WHERE TRY_CONVERT(NVARCHAR(50), sourceID) = TRY_CONVERT(NVARCHAR(50), faunaSource)) + '"'
WHEN 15 THEN 'Infection detected "' + (SELECT TOP 1 sourceText FROM @DS WHERE TRY_CONVERT(NVARCHAR(50), sourceID) = TRY_CONVERT(NVARCHAR(50), faunaSource)) + '"'
WHEN 23 THEN 'Forward on "' + (SELECT TOP 1 cellComplex FROM @CL WHERE TRY_CONVERT(NVARCHAR(50), cellID) = TRY_CONVERT(NVARCHAR(50), faunaSource)) + '"'
WHEN 45 THEN 'Traced cell "' + ISNULL((SELECT TOP 1 cellComplex FROM @CL WHERE TRY_CONVERT(NVARCHAR(50), cellID) = TRY_CONVERT(NVARCHAR(50), faunaSource)), '') + '"'
WHEN 77 THEN 'Sampled on "' + (SELECT TOP 1 cellComplex FROM @CL WHERE TRY_CONVERT(NVARCHAR(50), cellID) = TRY_CONVERT(NVARCHAR(50), faunaSource)) + '"<br />[' + faunaMessage + ']'
END As FaunaName
FROM @FT el
SELECT *,
CASE el.faunaType
WHEN 2 THEN 'Examine "' + ISNULL(cellComplex, '') + '"'
WHEN 9 THEN 'Investigate "' + ISNULL(sourceText, '') + '"'
WHEN 15 THEN 'Infection detected "' + ISNULL(sourceText, '') + '"'
WHEN 23 THEN 'Forward on "' + ISNULL(cellComplex, '') + '"'
WHEN 45 THEN 'Traced cell "' + ISNULL(cellComplex, '') + '"'
WHEN 77 THEN 'Sampled on "' + ISNULL(cellComplex, '') + '"<br />[' + faunaMessage + ']'
END As FaunaName
FROM @FT el
LEFT JOIN @DS ds ON ds.sourceID=el.faunaSource
LEFT JOIN @CL cl ON cl.cellID=el.faunaSource
评论
try_convert
cellList
TOP (1)
ORDER BY
SELECT cL.cellComplex FROM dbo.cellList cL WHERE cL.cellID = cL.faunaSource