首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何删除此慢速SQL中的连接

如何删除此慢速SQL中的连接
EN

Stack Overflow用户
提问于 2021-03-30 00:39:11
回答 1查看 73关注 0票数 0

我在SQL Server 2012上运行了以下(模糊处理的) SQL,需要显著提高其性能。它是有效的,但有时需要超过60秒才能恢复。

我想提取JOINS,但this post似乎表明这是不可能的(因为MINMAX) -那么如何提高性能并简化/改进这些连接呢?

代码语言:javascript
运行
复制
SELECT
    wm.id, wm.uid, wm.em, wm.fn, wm.ln, c, y, RTRIM(LTRIM(yCode)) AS yCode, wm.d1, ISNULL(wm.ffn, wm.pp) as ffn, wm.ada,
    case
        when wm.mss & 2=2
        then 'false'
        else 'true'
    end AS isa,
    (
        SELECT ', '+RTRIM(p1.cKey)
        FROM profile p1
            inner join loc stl on p1.cKey=stl.cKey
        WHERE p1.id = wm.id and p1.s = 'A'
        FOR XML PATH('')
    ) [lst],
    lishc.[lstCount],
    TotalCount = COUNT(*) OVER(),
    la.lsa, wskp.cKey AS pid
FROM wmm wm
    LEFT JOIN profile p1 ON wm.id = p1.id
    LEFT JOIN (
        SELECT UA.id, CONVERT(datetime, UA.ins, 1) As lsa
        FROM actlog UA
            INNER JOIN (
                select id, max(ins) as laa
                from actlog
                group by id
            ) UAJ on UA.id=UAJ.id and UA.ins=UAJ.laa
    ) la on la.id=wm.id
    LEFT JOIN (
        SELECT id, cKey FROM (
            SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY d1 desc) AS ROWNUM 
            FROM keypro where sc = 'SAP' AND cKeyDesc = 'SAP Agent ID'
        ) x WHERE ROWNUM = 1
    ) wskp ON wskp.id = wm.id
    LEFT JOIN (
        (SELECT p1.id ,COUNT(p1.cKey) AS [lstCount]
        FROM profile p1
            inner join loc stl on p1.cKey=stl.cKey
        where p1.s = 'A'
        GROUP BY p1.id)
    ) lishc ON lishc.id = wm.id
WHERE (@id = 0 OR wm.id = @id)
    AND (@uid IS NULL OR wm.uid LIKE '%' + @uid + '%')
    AND (@c IS NULL OR wm.c LIKE '%' + @c + '%')
    AND (@fn IS NULL OR wm.fn LIKE '%' + @fn + '%')
    AND (@ln IS NULL OR wm.ln LIKE '%' + @ln + '%')
    AND (@em IS NULL OR wm.em LIKE '%' + @em + '%')
    AND (@ffn IS NULL OR (wm.ffn LIKE '%' + @ffn + '%' OR wm.pp LIKE '%' + @ffn + '%'))                                                                
    AND (@pid IS NULL OR wskp.cKey LIKE '%' + @pid + '%' )
    AND (@Date1 IS NULL OR (CAST(wm.d1 AS DATE) BETWEEN CAST(@Date1 AS DATE) AND CAST(@Date2 AS DATE)))
    AND (@lsa1 IS NULL OR (CAST(la.lsa AS DATE) BETWEEN CAST(@lsa1 AS DATE) AND CAST(@lsa2 AS DATE)))
    AND (@Active IS NULL OR (wm.mss & 2 != 2))
    AND (@Inactive IS NULL OR (wm.mss & 2 = 2))
    AND (@External IS NULL OR (wm.ada = 'biz'))
    AND (@Internal IS NULL OR (wm.ada <> 'biz'))
    AND (@ApplyyFilter =0  OR (wm.yCode IN (SELECT @yCode WHERE 1 = 0))) 
    AND (@ApplylstFilter = 0 OR(p1.cKey IN (SELECT @ShipToList WHERE 1 = 0)))
    AND (@ApplylstFilter = 0 OR(p1.s = 'A'))
    AND (@ApplyNoFilter = 0 OR (lishc.[lstCount] is null))
    AND (@lstCount = 0 OR lishc.[lstCount] = @lstCount)
    AND (@ApplyLimitedFilter = 0 OR (wm.id IN (0)))
    AND (@ApplyMoreFilter = 0 OR (wm.id IN (SELECT @idss WHERE 1 = 0)))
GROUP BY wm.id, wm.uid, wm.em, wm.fn, wm.ln, y, yCode,c,wm.d1,wm.ffn,wm.mss,wm.ada, la.lsa, wskp.cKey, lishc.[lstCount], wm.pp
ORDER BY lsa DESC
OFFSET @PageOffset ROWS FETCH NEXT @PageSize ROWS ONLY
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-30 00:45:38

这里的捷径是添加OPTION (RECOMPILE),以便SQL Server可以消除与null参数相对应的谓词,并为每次搜索创建一个新计划。

你看,通常是Dynamic Search Conditions in T‑SQL

下一步要做的就是尽可能地去掉通配符搜索。

并改变这一点

代码语言:javascript
运行
复制
 (CAST(la.lsa AS DATE) BETWEEN CAST(@lsa1 AS DATE) AND CAST(@lsa2 AS DATE)))

转换成一个SARGable模式,比如

代码语言:javascript
运行
复制
 la.lsa >= @lsa1 and la.lsa < @lsa2

然后开始拆分这个查询,并为最常见或最关键的情况手写单独的查询。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66858124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档