Sql server 2008 优化';s使用15%的cpu时间
下面的查询占用了sql server上%15的cpu时间Sql server 2008 优化';s使用15%的cpu时间,sql-server-2008,Sql Server 2008,下面的查询占用了sql server上%15的cpu时间 declare @JobQueueId int = NULL, @JobTypeId int = NULL, @JobTypeIdHasValue BIT = 0, @TargetId int = NULL, @TargetIdHasValue BIT = 0, @JobMessage nvarchar(max) = NULL, @ComputerName nvarchar(60) = NULL, @
declare
@JobQueueId int = NULL, @JobTypeId int = NULL, @JobTypeIdHasValue BIT = 0, @TargetId int = NULL, @TargetIdHasValue BIT = 0,
@JobMessage nvarchar(max) = NULL, @ComputerName nvarchar(60) = NULL, @ComputerNameHasValue BIT = 0, @StartedOn datetime = NULL,
@StartedOnHasValue BIT = 0, @CompletedOn datetime = NULL, @CompletedOnHasValue BIT = 0, @SkipOrderedBy datetime = NULL,
@SkipOrderedByHasValue BIT = 0, @SkipOrderedOn datetime = NULL, @SkipOrderedOnHasValue BIT = 0, @Attempts int = NULL,
@AttemptsHasValue BIT = 0, @FailResult nvarchar(max) = NULL, @FailResultHasValue BIT = 0, @CreatedBy uniqueidentifier = NULL,
@CreatedOn datetime = NULL
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT [JobQueueId], [JobTypeId], [TargetId], [JobMessage], [ComputerName], [StartedOn], [CompletedOn], [SkipOrderedBy], [SkipOrderedOn], [Attempts], FailResult], [CreatedBy], [CreatedOn]
FROM [dbo].[JobQueue]
WHERE
([JobQueueId] = @JobQueueId OR @JobQueueId IS NULL)
AND ([JobTypeId] = @JobTypeId OR (@JobTypeId IS NULL AND @JobTypeIdHasValue = 0))
AND ([TargetId] = @TargetId OR (@TargetId IS NULL AND @TargetIdHasValue = 0))
AND ([JobMessage] = @JobMessage OR @JobMessage IS NULL)
AND ([ComputerName] = @ComputerName OR (@ComputerName IS NULL AND @ComputerNameHasValue = 0))
AND ([StartedOn] = @StartedOn OR (@StartedOn IS NULL AND @StartedOnHasValue = 0))
AND ([CompletedOn] = @CompletedOn OR (@CompletedOn IS NULL AND @CompletedOnHasValue = 0))
AND ([SkipOrderedBy] = @SkipOrderedBy OR (@SkipOrderedBy IS NULL AND @SkipOrderedByHasValue = 0))
AND ([SkipOrderedOn] = @SkipOrderedOn OR (@SkipOrderedOn IS NULL AND @SkipOrderedOnHasValue = 0))
AND ([Attempts] = @Attempts OR (@Attempts IS NULL AND @AttemptsHasValue = 0))
AND ([FailResult] = @FailResult OR (@FailResult IS NULL AND @FailResultHasValue = 0))
AND ([CreatedBy] = @CreatedBy OR @CreatedBy IS NULL)
AND ([CreatedOn] = @CreatedOn OR @CreatedOn IS NULL)
有人能提供一些指针来帮助我优化这个查询吗?因为查询可能会缓存一个支持特定参数的计划,所以不同的参数很可能不会从该计划中受益匪浅(搜索“参数嗅探”,您会发现这是一个非常常见的问题)。有两种选择:
sp_configure
)针对临时工作负载进行优化(请参阅和),并将查询更改为使用动态SQL。换句话说,按如下方式构建查询:
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT ... FROM [dbo].[JobQueue] WHERE 1=1';
IF @JobQueueId IS NOT NULL
SET @sql = @sql + N' AND JobQueueId = @JobQueueId';
-- ... repeat for other params
EXEC sp_executesql
@sql,
N'@JobQueueId INT, ..., @CreatedOn DATETIME',
@JobQueueId, ..., @CreatedOn;
另请参见:这是一个非常糟糕的查询。and和OR(及其模式)的绝对数量使得任何关于索引的静态推理都是徒劳的。它如此糟糕的主要原因是因为它是“通用的”:很多应该是静态的工作(比如检查@JobQueueId是否为null)都留给了SQL server
由于您不会从任何类型的查询准备中获益,因此您应该以动态方式构造查询,并让db server针对每个特定情况优化您的选择。尝试查看执行计划。评估你的指数,它们有意义吗?表上有索引吗?你还需要更多吗?看看我已经通过DTA运行了查询。大约有13个索引和42个统计数据。我只需要在这一点上重做查询。它只是消耗了服务器,一分钟运行很多次。我将第二、第三和第四个@driis所说的内容。我最近花了几天时间试图找出一个性能问题,结果是由于几个索引丢失。Tuning Advisor没有给我任何建议。它有所有需要的索引,我想你已经知道了。目前,存储过程是使用csla开发的。但我认为它需要一些改进,我认为你的第三个选择可能是最好的选择。谢谢你的意见。当我们做出改变时,我会记住这一点。