我可以改进这个T-SQL搜索吗?
编辑: 感谢这些回复,我将代码进一步整理为以下内容:我可以改进这个T-SQL搜索吗?,sql,sql-server,Sql,Sql Server,编辑: 感谢这些回复,我将代码进一步整理为以下内容: SELECT AllAlerts.AlertID as AlertID, Queues.QueueID as QueueID, Queues.QueueName as QueueName, AllAlerts.ConnectorID as ConnectorID, cast( ISNULL(STUFF ( ( select cast(',' as varchar(max)) + Serv
SELECT
AllAlerts.AlertID as AlertID,
Queues.QueueID as QueueID,
Queues.QueueName as QueueName,
AllAlerts.ConnectorID as ConnectorID,
cast( ISNULL(STUFF ( (
select cast(',' as varchar(max)) + Services.Label
from (
SELECT distinct Services.Label
from [ISG_SOI ].[dbo].[SecureServiceCI] as Services
inner join [ISG_SOI ].[dbo].[CIRelationship] as Relationship
on Relationship.BNodeCIID = AllAlerts.CIID
where Services.CIID = Relationship.ServiceCIID
) as Services
for xml path ('')
), 1, 1, ''), '') as CHAR(1000)) as OwnedServices,
right(AllAlerts.DeviceID, len(AllAlerts.DeviceID)-charindex(',', AllAlerts.DeviceID)) as CIName,
AllAlerts.DeviceID as DeviceID,
AllAlerts.SituationMessage as Summary,
AllAlerts.AlertDetail as Detail,
AllAlerts.Acknowledged as Acknowledged,
AllAlerts.AssignedTo as AssignedTo,
AllAlerts.ReportedTime as CreatedTime,
AllAlerts.ClearedTime as ClearedTime,
AllAlerts.Severity as Severity,
AllAlerts.SvcDeskTicket as TicketID,
ISNULL(STUFF ( (
select cast('# ' as varchar(max)) + Notes.AnnotationText + '[' + Notes.CreatedBy + ', ' + cast(Notes.CreatedTime as varchar(max)) + ']'
from [ISG_SOI ].[dbo].[AlertAnnotation] as Notes
where Notes.AlertID = AllAlerts.AlertID
for xml path('')
), 1, 1, ''), '') as Notes
from
[ISG_SOI ].[dbo].[Alerts] as AllAlerts
inner join [ISG_SOI ].[dbo].[AlertQueueAssignments] as QA
on QA.[AlertID] = AllAlerts.[AlertID]
inner join [ISG_SOI ].[dbo].[AlertQueues] AS Queues
on Queues.[QueueID] = QA.[QueueID]
where Queues.QueueName = 'OCC'
-原职-
我一直在为一个我正在工作的项目进行T-SQL搜索,最终得到了搜索参数,以获得我需要的所有结果。不过我很好奇,有没有办法改进这个命令?您必须原谅我,因为我不是SQL专家
SELECT AllAlerts.AlertID AS AlertID
,Queues.QueueID AS QueueID
,Queues.QueueName AS QueueName
,AllAlerts.ConnectorID AS ConnectorID
,CAST(ISNULL(STUFF(( SELECT CAST(',' AS VARCHAR(MAX)) + Services.Label
FROM ( SELECT DISTINCT Services.Label
FROM [ISG_SOI ].[dbo].[SecureServiceCI] AS Services
WHERE Services.CIID IN (
SELECT Relationship.ServiceCIID
FROM [ISG_SOI ].[dbo].[CIRelationship] AS Relationship
WHERE Relationship.BNodeCIID = AllAlerts.CIID ) ) AS Services
FOR
XML PATH('') ), 1, 1, ''), '') AS CHAR(1000)) AS OwnedServices
,RIGHT(AllAlerts.DeviceID, LEN(AllAlerts.DeviceID) - CHARINDEX(',', AllAlerts.DeviceID)) AS CIName
,AllAlerts.DeviceID AS DeviceID
,AllAlerts.SituationMessage AS Summary
,AllAlerts.AlertDetail AS Detail
,AllAlerts.Acknowledged AS Acknowledged
,AllAlerts.AssignedTo AS AssignedTo
,AllAlerts.ReportedTime AS CreatedTime
,AllAlerts.ClearedTime AS ClearedTime
,AllAlerts.Severity AS Severity
,AllAlerts.SvcDeskTicket AS TicketID
,ISNULL(STUFF(( SELECT CAST('# ' AS VARCHAR(MAX)) + Notes.AnnotationText + '[' + Notes.CreatedBy + ', '
+ CAST(Notes.CreatedTime AS VARCHAR(MAX)) + ']'
FROM [ISG_SOI ].[dbo].[AlertAnnotation] AS Notes
WHERE Notes.AlertID = AllAlerts.AlertID
FOR
XML PATH('') ), 1, 1, ''), '') AS Notes
FROM [ISG_SOI ].[dbo].[Alerts] AS AllAlerts
,[ISG_SOI ].[dbo].[AlertQueues] AS Queues
WHERE AllAlerts.AlertID IN ( SELECT QueueAssignment.AlertID
FROM [ISG_SOI ].[dbo].[AlertQueueAssignments] AS QueueAssignment
WHERE QueueAssignment.QueueID IN ( SELECT Queues.QueueID
WHERE Queues.QueueName = 'OCC' ) )
您正在使用大量嵌套选择,这很慢,因为您可能正在评估每个上层行的选择。而是使用公共表表达式CTE,它使您能够预先进行选择
WITH MyCTE AS (
SELECT distinct Services.Label
from [ISG_SOI ].[dbo].[SecureServiceCI] as Services
where Services.CIID in (
select Relationship.ServiceCIID
from [ISG_SOI ].[dbo].[CIRelationship] as Relationship
where Relationship.BNodeCIID = AllAlerts.CIID
)
SELECT
AllAlerts.AlertID as AlertID,
Queues.QueueID as QueueID,
Queues.QueueName as QueueName,
AllAlerts.ConnectorID as ConnectorID,
cast( ISNULL(STUFF ( (
select cast(',' as varchar(max)) + Services.Label
from (
MyCTE
) as Services
您可以为每个嵌套查询定义多个CTE,以说明基于我的注释的部分解决方案:
from [ISG_SOI ].[dbo].[Alerts] AS AllAlerts
inner join [ISG_SOI ].[dbo].[QueueAssignment] as QA on QA.[AlertID] = AllAlerts.[AlertID]
inner join [ISG_SOI ].[dbo].[AlertQueues] AS Queues on Queues.[QueueID] = QA.[QueueID]
where Queues.QueueName = 'OCC'
您只剩下一个嵌套子查询,而不是三个嵌套子查询
对于xml子查询,可以对第一个子查询进行相同的改进—同样,您正在做一些事情—连接是为使用子查询而做的。谢谢大家的帮助!下面是基于注释输入的代码的最终结果
SELECT
AllAlerts.AlertID as AlertID,
Queues.QueueID as QueueID,
Queues.QueueName as QueueName,
AllAlerts.ConnectorID as ConnectorID,
cast( ISNULL(STUFF ( (
select cast(',' as varchar(max)) + Services.Label
from (
SELECT distinct Services.Label
from [ISG_SOI ].[dbo].[SecureServiceCI] as Services
inner join [ISG_SOI ].[dbo].[CIRelationship] as Relationship
on Relationship.BNodeCIID = AllAlerts.CIID
where Services.CIID = Relationship.ServiceCIID
) as Services
for xml path ('')
), 1, 1, ''), '') as CHAR(1000)) as OwnedServices,
right(AllAlerts.DeviceID, len(AllAlerts.DeviceID)-charindex(',', AllAlerts.DeviceID)) as CIName,
AllAlerts.DeviceID as DeviceID,
AllAlerts.SituationMessage as Summary,
AllAlerts.AlertDetail as Detail,
AllAlerts.Acknowledged as Acknowledged,
AllAlerts.AssignedTo as AssignedTo,
AllAlerts.ReportedTime as CreatedTime,
AllAlerts.ClearedTime as ClearedTime,
AllAlerts.Severity as Severity,
AllAlerts.SvcDeskTicket as TicketID,
ISNULL(STUFF ( (
select cast('# ' as varchar(max)) + Notes.AnnotationText + '[' + Notes.CreatedBy + ', ' + cast(Notes.CreatedTime as varchar(max)) + ']'
from [ISG_SOI ].[dbo].[AlertAnnotation] as Notes
where Notes.AlertID = AllAlerts.AlertID
for xml path('')
), 1, 1, ''), '') as Notes
from
[ISG_SOI ].[dbo].[Alerts] as AllAlerts
inner join [ISG_SOI ].[dbo].[AlertQueueAssignments] as QA
on QA.[AlertID] = AllAlerts.[AlertID]
inner join [ISG_SOI ].[dbo].[AlertQueues] AS Queues
on Queues.[QueueID] = QA.[QueueID]
where Queues.QueueName = 'OCC'
我删除了MySQL标记,因为这是明确关于SQL Server的。上一条语句中缺少了您。几乎可以保证可以以更好的方式重写它。您正在疯狂地使用子查询,尽管似乎至少where子句可以使用简单的内部联接轻松地重写,这将显著提高性能。作为一个基本的规则,子查询是昂贵的,如果可能的话,你几乎总是想用连接来替换它们。。。没想到反应这么快,你们太棒了。当我从你们的话中得到一些知识时,让我看看每个人的反应和回答。谢谢请把最后的代码放在答案中,而不是问题中。谢谢你,我实际上从这篇评论中学到了一些语法。我希望我能投票,但还没有代表:@paimon.soror你应该能够将我的答案标记为正确,除非我弄错了:@paimon.soror总是乐于帮助;这很好,我将不得不做一些阅读使用CTE的,以获得更好的理解。谢谢你抽出时间!所以我做了一些阅读,看起来这里的问题是,在我的内部选择中,我使用了'AllAlerts.CIID'。如果我将select移出到CTE,它将不会引用“AllAllerts”,因为这是主查询的一部分。除非有办法将参数传递给CTE,但我认为这是不可能的。