微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何优化或加速以下 sql 查询?

如何解决如何优化或加速以下 sql 查询?

所以我有以下 sql 查询,顺便说一下,它在数据提取方面工作正常。唯一的问题是检索数据需要很长时间。

select distinct cast(bb.idPrefix as varchar)+'-'+cast(bb.id as varchar) as 'TicketID',bb.Title,bb.Description,bb.Submitter,bb.IssueType,bb.Progressstatus as 'Status',bb.Resolution,bb.CurrentOwner as 'Assignee',bb.TimeEstimated / 60 as 'TimeEstimated (minutes)',bb.TimeRemaining /60 as 'TimeRemaining (minutes)',bb.TimeLogged /60 as 'TimeSpent (minutes)',bb.Projectname,case when bb.id in (Select id from project.sprint GROUP BY id HAVING COUNT(*) > 1) and 
                      (Select count(*) from project.sprint where id = bb.Id GROUP BY id HAVING COUNT(*) > 1) >1 then 
                      (select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid desc)
     when bb.id in (Select id from project.sprint GROUP BY id HAVING COUNT(*) > 1) and 
                      (Select count(*) from project.sprint where id = bb.id GROUP BY id HAVING COUNT(*) > 1) >1 then 
                      (select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid desc)
                       else null end as 'End Sprint',case when bb.id in (Select id from project.sprint GROUP BY id HAVING COUNT(*) > 1) and 
                      (Select count(*) from project.sprint where id = bb.id GROUP BY id HAVING COUNT(*) > 1) > 1 then 
                      (select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid Asc)
     when bb.id in (Select id from project.sprint GROUP BY id HAVING COUNT(*) > 1) and 
                      (Select count(*) from project.sprint where id = bb.id GROUP BY id HAVING COUNT(*) > 1) > 1 then 
                      (select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid Asc) end as 'Start Sprint',case when bb.resolution is null and bb.TimeEstimated is null and bb.CurrentOwner is null then 1 else 0 end as 'Backlog',case when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid asc),14,1) like '[0-9]' then substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid asc),1)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid asc),15,2)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid asc),16,3)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid asc),12,1) like '[0-9]' then substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid asc),1)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid asc),13,2)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid asc),3) else 0 end as [StartCO],case when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid desc),1) like '[0-9]' then substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid desc),1)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid desc),2)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'XXXXX sprint%' order by sprintid desc),3)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid desc),1) like '[0-9]' then substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid desc),1)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid desc),2)
     when substring((select top 1 SprintName from project.sprint where id = bb.id and bb.projectid = 12345 and sprintname like 'YYY sprint%' order by sprintid desc),3) else 0 end as [EndCO]
from project.bugs bb 
left join project.sprint bs on
bb.id = bs.id 
left join project.logs l on 
bb.id = l.id
where bb.projectid = 18540
and bb.IssueType = 'tracking' and bb.idPrefix like 'Test%' and (bb.title like '%XXXXX%auto%' or bb.title like '%YYY%auto%')

有什么想法可以更改以加快此过程吗?

解决方法

这里到处都是我添加的评论。有些人注意到所需的行为是未知的/不可能的,因此需要解决。但是,我相信我重写了正确的逻辑。我摆脱了几乎所有的子查询栏 2;我将其余部分移到 FROM 中的 OUTER APPLY。当然,这是不可能测试的,因为我没有样本数据,也没有预期的结果,但是,SQL确实解析:

SELECT CAST(bb.idPrefix AS varchar) + '-' + CAST(bb.id AS varchar) AS TicketID,--Don't use single quotes for aliases,they are for literal strings
       bb.Title,bb.Description,bb.Submitter,bb.IssueType,bb.ProgressStatus AS Status,they are for literal strings
       bb.Resolution,bb.CurrentOwner AS Assignee,they are for literal strings
       bb.TimeEstimated / 60 AS TimeEstimatedMinutes,they are for literal strings. Also,stick to names that don't need delimit identifing
       bb.TimeRemaining / 60 AS TimeRemainingMinutes,they are for literal strings.  Also,stick to names that don't need delimit identifing
       bb.TimeLogged / 60 AS TimeSpentMinutes,stick to names that don't need delimit identifing
       bb.Projectname,CASE
            WHEN (SELECT COUNT(*)
                  FROM project.sprint s
                  WHERE s.id = bb.Id
                  --HAVING is pointless when you're checking in the CASE. If you want to use a HAVING use EXISTS in the CASE
                  GROUP BY id) > 1 THEN SNx.SprintName
            --This will never be true,it's the same as the last WHEN
            /*
            WHEN (SELECT COUNT(*)
                  FROM project.sprint s
                  WHERE s.id = bb.id
                  GROUP BY id
                  --HAVING is pointless when you're checking in the CASE. If you want to use a HAVING use EXISTS in the CASE
                  HAVING COUNT(*) > 1) > 1 THEN SNy.SprintName 
            */
       --ELSE NULL is redundant,a CASE expression already returns NULL if it doesn't evaluate to TRUE
       END AS EndSprint,stick to names that don't need delimit identifing
       CASE
            WHEN (SELECT COUNT(*)
                  FROM project.sprint s
                  WHERE s.id = bb.id
                  --HAVING is pointless when you're checking in the CASE. If you want to use a HAVING use EXISTS in the CASE
                  GROUP BY id) > 1 THEN SNx.SprintName
            --This will never be true,a CASE expression already returns NULL if it doesn't evaluate to TRUE
       END AS StartSprint,stick to names that don't need delimit identifing
       CASE
            WHEN bb.resolution IS NULL
             AND bb.TimeEstimated IS NULL
             AND bb.CurrentOwner IS NULL THEN 1
            ELSE 0
       END AS Backlog,they are for literal strings
       CASE
            WHEN SUBSTRING(SNx.SprintName,14,1) LIKE '[0-9]' THEN SUBSTRING(SNx.SprintName,1)
            WHEN SUBSTRING(SNx.SprintName,15,2)
            WHEN SUBSTRING(SNx.SprintName,16,3)
            WHEN SUBSTRING(SNy.SprintName,12,1) LIKE '[0-9]' THEN SUBSTRING(SNy.SprintName,1)
            WHEN SUBSTRING(SNy.SprintName,13,2)
            WHEN SUBSTRING(SNy.SprintName,3)
            ELSE 0
       END AS StartCO,CASE
            WHEN SUBSTRING(SNx.SprintName,3)
            ELSE 0
       END AS EndCO
FROM project.bugs bb
     OUTER APPLY (SELECT TOP 1
                         s.SprintName
                  FROM project.sprint s
                  WHERE s.id = bb.id
                    AND bb.projectid = 12345
                    AND s.sprintname LIKE 'XXXXX sprint%'
                  ORDER BY s.sprintid ASC) SNx
     OUTER APPLY (SELECT TOP 1
                         s.SprintName
                  FROM project.sprint s
                  WHERE s.id = bb.id
                    AND bb.projectid = 12345
                    AND s.sprintname LIKE 'YYY sprint%'
                  ORDER BY s.sprintid ASC) SNy
WHERE bb.projectid = 18540
  AND bb.IssueType = 'tracking'
  AND bb.idPrefix LIKE 'Test%'
  AND (bb.title LIKE '%XXXXX%auto%' --This will never be SARGable due to leading wildcard.
    OR bb.title LIKE '%YYY%auto%'); --This will never be SARGable due to leading wildcard.

当然,索引是另一回事,但如果没有对象的完整 DDL 和 DML 以及执行计划(如果结果正确,则该查询的执行计划),我什至不会在这里开始娱乐。

,

使用 WITH 语句提取常见查询。这是 SQL Server 中的 CTE 或公共表表达式。

您不必在 WITH 语句中执行整个子查询,只需简化数据即可。

例如:

WITH MY_SPRINT_QUERY AS
{
select Id,SprintName,sprintId from project.sprint 
where 
(sprintname like "XXXXX sprint%")
OR 
(sprintname like "YYY sprint%")
}
SELECT <insert your simplified query here>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。