简体   繁体   中英

Can I Make This T-SQL Search Better?

EDIT:

Thanks to the responses, I have further cleaned up the code to the following:

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'

-- ORIGINAL POST --

I have been working on a T-SQL search for a project that I am working on at work and finally got the search parameters down to get back all the results that I need. I was curious though, is there any way to improve on this command? You will have to forgive me as I am not a SQL expert.

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' ) )

You are using a lot of nested SELECTS, which are slow because you may be evaluating the SELECTS for each upper level row. Rather use Common Table Expressions (CTE) which enable you to do your SELECT upfront.

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

You can define multiple CTE for each of your nested queries

To illustrate a partial solution based on my comment:

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'

Instead of three nested subqueries, you're left with just one.

The same improvement can be made to the first for xml subquery - again, you're doing something joins are made for using subqueries.

Thanks everyone for the help! Here is the final outcome of the code based on input from the comments!

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'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM