Время ожидания процедуры SQL Server истекло

У меня возникают промежуточные тайм-ауты при вызове этой хранимой процедуры из внешней среды ASP.NET на производственном сайте. он возвращает следующее исключение sql:

Сведения об исключении: System.Data.SqlClient.SqlException: истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает.

Забавно то, что при выполнении этой процедуры на сервере или с удаленного компьютера с помощью Management Studio она выполняется за 6 секунд. Но тем не менее, иногда истекает время ожидания при выполнении из приложения ASP.NET? Можно ли улучшить этот запрос? Или эта проблема связана с чем-то другим? Кто может помочь? Я читал несколько тем об увеличении тайм-аута и включении пула в строке подключения в моем web.config, но еще не пробовал этого.

 ALTER PROCEDURE [dbo].[Report_Activity]
    (
        @StartDate      DATETIME
    ,   @EndDate        DATETIME
    ,   @TotalActions INT OUTPUT
    )

    AS
    BEGIN 

        SELECT      @TotalActions = COUNT(EventHistoryId)
        FROM        dbo.SessionEventHistory
        WHERE       DateCreated BETWEEN @StartDate AND @EndDate

        SELECT      EventDescription, COUNT(EventHistoryId) AS EventCount           
        FROM        dbo.SessionEventHistory
        WHERE       DateCreated BETWEEN @StartDate AND @EndDate
        GROUP BY    EventDescription
        ORDER BY    EventDescription

СХЕМЫ SQL:

CREATE TABLE [dbo].[SessionEventHistory](
    [EventHistoryID] [int] IDENTITY(1,1) NOT NULL,
    [SessionHistoryID] [int] NOT NULL,
    [CategoryID] [int] NULL,
    [UserName] [nvarchar](50) NULL,
    [IPAddress] [nvarchar](20) NOT NULL,
    [EventDescription] [nvarchar](1000) NOT NULL,
    [EventData] [varbinary](max) NULL,
    [DateCreated] [datetime] NOT NULL,
 CONSTRAINT [PK_UserEventHistory] PRIMARY KEY CLUSTERED 
(
    [EventHistoryID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[SessionEventHistory] ADD  CONSTRAINT [DF_UserEventHistory_DateCreated]  DEFAULT (getdate()) FOR [DateCreated]
GO

Таблица имеет 3 индекса:

/****** Object:  Index [IX_SessionEventHistory_SessionHistoryId_CategoryId]    Script Date: 07/04/2012 10:47:06 ******/
CREATE NONCLUSTERED INDEX [IX_SessionEventHistory_SessionHistoryId_CategoryId] ON [dbo].[SessionEventHistory] 
(
    [SessionHistoryID] ASC,
    [CategoryID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO


/****** Object:  Index [IX_SessionEventHistory_UserName_DateCreated]    Script Date: 07/04/2012 10:47:09 ******/
CREATE NONCLUSTERED INDEX [IX_SessionEventHistory_UserName_DateCreated] ON [dbo].[SessionEventHistory] 
(
    [UserName] ASC,
    [DateCreated] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO


/****** Object:  Index [PK_UserEventHistory]    Script Date: 07/04/2012 10:47:14 ******/
ALTER TABLE [dbo].[SessionEventHistory] ADD  CONSTRAINT [PK_UserEventHistory] PRIMARY KEY CLUSTERED 
(
    [EventHistoryID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

ИЗМЕНИТЬ

Я добавил следующий указатель, все в порядке?

CREATE NONCLUSTERED INDEX [IX_SessionEventHistory_DateCreated] ON [dbo].[SessionEventHistory] 
(
    [DateCreated] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

введите описание изображения здесь


person FaNIX    schedule 04.07.2012    source источник
comment
Размещение индекса на [DateCreated], вероятно, поможет   -  person DJ.    schedule 04.07.2012
comment
@DJ Я согласен, этот индекс, вероятно, повысит общую эффективность, но если один и тот же запрос с одинаковыми параметрами ведет себя по-разному в разных приложениях, вероятно, дело не только в этом.   -  person Aaron Bertrand    schedule 04.07.2012
comment
Уже есть индекс на DateCreated (IX_SessionEventHistory_UserName_DateCreated)?   -  person FaNIX    schedule 04.07.2012
comment
@FaNIX, но этот индекс не имеет DateCreated в качестве ведущего столбца. Таким образом, если запрос также не включает предложение или группу where, включая столбец UserName, вы должны увидеть в плане выполнения, что этот индекс не используется для удовлетворения этого запроса.   -  person Aaron Bertrand    schedule 04.07.2012
comment
Это может быть обнюхивание параметров - попробуйте использовать локальные переменные даты - также просмотрите отличные ссылки, которые Аарон разместил ниже ...   -  person DJ.    schedule 04.07.2012
comment
Я добавил код для нового индекса выше.   -  person FaNIX    schedule 04.07.2012
comment
6 секунд - довольно длинный запрос. Посмотрите на план запроса. Он может порекомендовать новый индекс. Поскольку вы группируете по EventDescription, это главный кандидат для индекса. И индексы фрагментированы?   -  person paparazzo    schedule 04.07.2012
comment
Извините, ребята, я не гуру по оптимизации SQL, так что для меня это все в новинку. Приложил план исполнения. Он рекомендует добавить индекс в DateCreated, что я уже сделал, но он все еще отображает это сообщение?   -  person FaNIX    schedule 04.07.2012


Ответы (2)


Взгляните на sys.dm_exec_sessions для своего приложения ASP.Net и для сеанса SSMS. Рискну предположить, что по крайней мере одна из ваших SET настроек отличается. Это может повлиять на разные планы (в конечном итоге это связано с анализом параметров), и сторона приложения обычно оказывается в худшем положении.

См. Эти другие вопросы для получения более подробной информации:

Хранимая процедура медленно при вызове из Интернета, быстро из Management Studio

Время процедуры истекло с ADO.NET, но не в SSMS

Время ожидания запроса истекает, когда выполняется из Интернета, но очень быстро при выполнении из SSMS

ADO .NET против SQL Server Management Studio - ADO выполняет хуже

Также прочтите эту замечательную статью Эрланда Соммарскога.

person Aaron Bertrand    schedule 04.07.2012
comment
Проблема была не в запросе, хотя его можно было немного оптимизировать. Проблема была в SQLDBCommand.CommandTimeout. По умолчанию это 30 секунд, в моей процедуре не было WITH (NOLOCK), поэтому, когда несколько пользователей запрашивают отчет, он значительно замедляется, затем превышает 30 секунд и бум, DBCommand закрывается с исключением SqlTimeout. Увеличив .CommandTimeout = 90 и введя WITH (NOLOCK), мы решили проблему :) - person FaNIX; 04.07.2012
comment
Что ж, я бы не стал называть любую из этих вещей исправлением, но рад, что вы накинули на это пластырь. :-) - person Aaron Bertrand; 04.07.2012

Возможно, это плохой план выполнения, созданный из-за какого-то нетипичного вызова SP. Попробуйте использовать WITH RECOMPILE либо при выполнении SP, либо в определении.

EXEC [dbo].[Report_Activity] @StartDate, @EndDate, @TotalActions WITH RECOMPILE

or

ALTER PROCEDURE [dbo].[Report_Activity]
    (
        @StartDate      DATETIME
    ,   @EndDate        DATETIME
    ,   @TotalActions INT OUTPUT
    )
WITH RECOMPILE
AS
...

Вы также можете запустить sp_recompile, чтобы пометить SP для перекомпиляции в следующий раз, когда он будет выполнен.

person dan radu    schedule 04.07.2012