TSQL:查看性能问题

时间:2015-09-29 06:23:37

标签: sql sql-server sql-server-2008 tsql

我遇到以下查询问题。它工作并给我所需的结果,但它很慢,因为我的子选择与连接。我的TSQL技能不足以优化此查询。也许你们中的一些人可以提供帮助。

SELECT
    Id AS InstanceId,
    (SELECT COUNT(DISTINCT tiq.Id) AS Expr1
     FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
            dbo.tProcessLog AS tpr ON tpr.InstanceConfigId = tic.Id AND tpr.InputQueueEntryId = tiq.Id
     WHERE  (tpr.ProcessResultId = 32)) AS Received,
    (SELECT COUNT(DISTINCT tiq.Id) AS Expr1
     FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
            dbo.tProcessLog AS tpr ON tpr.InstanceConfigId = tic.Id AND tpr.InputQueueEntryId = tiq.Id
     WHERE        (tiq.InMsgStateFlags = 1)) AS Queued,
    (SELECT COUNT(DISTINCT tiq.Id) AS Expr1
     FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
            dbo.tProcessLog AS tpr ON tpr.InstanceConfigId = tic.Id AND tpr.InputQueueEntryId = tiq.Id
     WHERE  (tiq.InMsgStateFlags = 2)) AS Processed,
    (SELECT COUNT(DISTINCT tiq.Id) AS Expr1
     FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
            dbo.tProcessLog AS tpr ON tpr.InstanceConfigId = tic.Id AND tpr.InputQueueEntryId = tiq.Id
     WHERE  (tiq.InMsgStateFlags = 128)) AS Error,
    (SELECT COUNT(DISTINCT tiq.Id) AS Expr1
     FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
            dbo.tProcessLog AS tpr ON tpr.InstanceConfigId = tic.Id AND tpr.InputQueueEntryId = tiq.Id
     WHERE  (tiq.InMsgStateFlags = 256)) AS Rejected,
    (SELECT COUNT(tiq.Id) AS Expr1
     FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
            dbo.tProcessLog AS tpr ON tpr.InstanceConfigId = tic.Id AND tpr.InputQueueEntryId = tiq.Id
     WHERE  (tpr.ProcessResultId = 16)) AS Duplicates,
    (SELECT COUNT(DISTINCT tiq.Id) AS Expr1
     FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
            dbo.tProcessLog AS tpr ON tpr.InstanceConfigId = tic.Id AND tpr.InputQueueEntryId = tiq.Id
     WHERE  (tpr.ProcessResultId = 2)) AS Nack 
FROM
    dbo.tInstanceConfig AS tic 
WHERE
    (InstanceGroupId = 1)

此查询作为视图运行。

如果您需要更多信息,请与我们联系。

这是表格信息

tProcessLog

    [Id] [bigint] IDENTITY(1,1) NOT NULL,
[InstanceConfigId] [int] NOT NULL,
[InputQueueEntryId] [bigint] NOT NULL,
[OutputQueueEntryId] [bigint] NULL,
[ProcessingDtm] [datetime] NOT NULL,
[ProcessResultId] [int] NOT NULL,
[SeverityId] [int] NOT NULL,
[LogText] [varchar](max) NOT NULL,
[IsHidden] [bit] NOT NULL,
[ReceiverId] [int] NOT NULL,

tInputQueueEntry

    [Id] [bigint] IDENTITY(1,1) NOT NULL,
[Created] [datetime] NOT NULL,
[DataTypeId] [int] NOT NULL,
[CodePage] [int] NOT NULL,
[InMsgStateFlags] [int] NOT NULL,
[ContentData] [nvarchar](max) NOT NULL,
[ContentHash] [nvarchar](32) NOT NULL,

tInstanceConfig

    [Id] [int] IDENTITY(1,1) NOT NULL,
[IsActive] [bit] NOT NULL,
[Type] [varchar](50) NOT NULL,
[Description] [varchar](50) NOT NULL,
[ComponentConfig] [xml] NOT NULL,
[InstanceGroupId] [int] NOT NULL,

更新

最后,我认为没有办法获得更多的性能。我使用了MSSQL Tuning Advisor,它有一些建议,现在查询耗时约500ms。这对我来说没问题。

感谢所有答案!我没有帮助性能问题,但我学到了很酷的新tsql东西:)

3 个答案:

答案 0 :(得分:2)

喜欢这个吗?

SELECT
    tic.Id AS InstanceId,
    count.*
FROM
    dbo.tInstanceConfig AS tic 
    OUTER APPLY
    (
        SELECT 
            COUNT(DISTINCT CASE WHEN tpr.ProcessResultId = 32 THEN tiq.Id END) AS Received,
            COUNT(DISTINCT CASE WHEN tiq.InMsgStateFlags = 1 THEN tiq.Id END) AS Queued,
            COUNT(DISTINCT CASE WHEN tiq.InMsgStateFlags = 2 THEN tiq.Id END) AS Processed,
            COUNT(DISTINCT CASE WHEN tiq.InMsgStateFlags = 128 THEN tiq.Id END) AS Error,
            COUNT(DISTINCT CASE WHEN tiq.InMsgStateFlags = 256 THEN tiq.Id END) AS Rejected,
            COUNT(DISTINCT CASE WHEN tpr.ProcessResultId = 16 THEN tiq.Id END) AS Duplicates,
            COUNT(DISTINCT CASE WHEN tpr.ProcessResultId = 2 THEN tiq.Id END) AS Nack
        FROM   
            dbo.tInputQueueEntry AS tiq 
            INNER JOIN dbo.tProcessLog AS tpr ON tpr.InstanceConfigId = tic.Id AND tpr.InputQueueEntryId = tiq.Id
    ) count
WHERE
    (InstanceGroupId = 1)

答案 1 :(得分:1)

DECLARE @Received INT,@Queued INT,@Processed INT,@Error INT,@Rejected INT,@Duplicates INT,@Nack INT

SET @Received =  SELECT COUNT(DISTINCT tiq.Id) AS Expr1
         FROM   
            dbo.tInputQueueEntry AS tiq 
         INNER JOIN
            dbo.tProcessLog AS tpr ON tpr.InputQueueEntryId = tiq.Id
         INNER JOIN dbo.tInstanceConfig AS tic ON tpr.InstanceConfigId = tic.Id
         WHERE  (tpr.ProcessResultId = 32)

SET @Queued =  SELECT COUNT(DISTINCT tiq.Id) AS Expr1
         FROM   
            dbo.tInputQueueEntry AS tiq 
        INNER JOIN
            dbo.tProcessLog AS tpr ON tpr.InputQueueEntryId = tiq.Id
         INNER JOIN dbo.tInstanceConfig AS tic ON tpr.InstanceConfigId = tic.Id
         WHERE        (tiq.InMsgStateFlags = 1) 

SET @Processed =  SELECT COUNT(DISTINCT tiq.Id) AS Expr1
                 FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
                        dbo.tProcessLog AS tpr ON tpr.InputQueueEntryId = tiq.Id
                        INNER JOIN dbo.tInstanceConfig AS tic ON tpr.InstanceConfigId = tic.Id
                 WHERE  (tiq.InMsgStateFlags = 2)   

SET @Error   = SELECT COUNT(DISTINCT tiq.Id) AS Expr1
                 FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
                        dbo.tProcessLog AS tpr ON tpr.InputQueueEntryId = tiq.Id
                        INNER JOIN dbo.tInstanceConfig AS tic ON tpr.InstanceConfigId = tic.Id 
                 WHERE  (tiq.InMsgStateFlags = 128)

SET @Rejected = SELECT COUNT(DISTINCT tiq.Id) AS Expr1
             FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
                    dbo.tProcessLog AS tpr ON tpr.InputQueueEntryId = tiq.Id
                    INNER JOIN dbo.tInstanceConfig AS tic tpr.InstanceConfigId = tic.Id
             WHERE  (tiq.InMsgStateFlags = 256) 

SET @Duplicates = SELECT COUNT(tiq.Id) AS Expr1
                 FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
                        dbo.tProcessLog AS tpr ON tpr.InputQueueEntryId = tiq.Id
                        INNER JOIN dbo.tInstanceConfig AS tic ON tpr.InstanceConfigId = tic.Id
                 WHERE  (tpr.ProcessResultId = 16)  
SET @Nack = SELECT COUNT(DISTINCT tiq.Id) AS Expr1
			 FROM   dbo.tInputQueueEntry AS tiq INNER JOIN
					dbo.tProcessLog AS tpr ON tpr.InputQueueEntryId = tiq.Id
					INNER JOIN dbo.tInstanceConfig AS tic ON tpr.InstanceConfigId = tic.Id
			 WHERE  (tpr.ProcessResultId = 2)                 

SELECT
    Id AS InstanceId,
    @Received AS Received,
    @Queued AS Queued,
    @Processed AS Processed,
    @Error AS Error,
    @Rejected AS Rejected,
    @Duplicates AS Duplicates,
    @Nack AS Nack 
FROM
    dbo.tInstanceConfig AS tic 
WHERE
    (InstanceGroupId = 1)

答案 2 :(得分:0)

您是否GROUP BY使用InMsgStateFlags并获取count(1)值,因为其他条件相同?只需写一个SELECT语句。