Хранимая процедура выполняется медленно при первом запуске - PullRequest
4 голосов
/ 25 октября 2010

Создана хранимая процедура, которая используется для целей мониторинга веб-сайта.

При первом запуске процедура занимает более минуты, а если выполняется вскоре после этого, она занимает всего несколько секунд.Проблема в том, что запуск сценария запланирован с интервалом в десять минут, и каждый раз, когда он запускается, это занимает более минуты, что слишком долго.

Кто-нибудь знает, как мы можем улучшить производительность этого запроса?Я знаю, что есть причина, по которой он запускается медленно в первый раз, а затем быстро для любого последующего, но не смог найти ответ.

Вот код, спасибо заранее:)

SET NOCOUNT ON
SET DATEFORMAT ymd

declare @start datetime
declare @end datetime
set @start = DATEADD(dd,-1,GETDATE())
set @end = GETDATE()

declare @errorToday int
declare @unconfirmedToday int

set @unconfirmedToday = 
(
 SELECT COUNT([DateCreated])
 FROM GenericLeadLogs WITH(NOLOCK)
 WHERE DestinationConfirmation IS NULL 
 AND [DateCreated] BETWEEN @start AND @end
)

SET @errorToday = 
(
 SELECT COUNT([DateCreated])
 FROM GenericLeadLogs WITH(NOLOCK)
 WHERE Severity = 'Error' 
 AND [DateCreated] BETWEEN @start AND @end
)

CREATE TABLE #GenericLeadStats 
(
 UnconfirmedToday int null, 
 ErrorToday int null
)

INSERT INTO #GenericLeadStats (UnconfirmedToday, ErrorToday)
values(@unconfirmedToday, @errorToday)

SELECT * FROM #GenericLeadStats
DROP TABLE #GenericLeadStats 

Ответы [ 3 ]

4 голосов
/ 25 октября 2010

Я переписал хранимую процедуру как:

SET NOCOUNT ON

SELECT SUM(CASE WHEN DestinationConfirmation IS NULL THEN 1 ELSE 0 END) AS unconfirmedToday,
       SUM(CASE WHEN Severity = 'Error' THEN 1 ELSE 0 END) AS errorToday
  INTO #GenericLeadStats
  FROM GenericLeadLogs WITH(NOLOCK) 
 WHERE [DateCreated] BETWEEN DATEADD(dd,-1,GETDATE()) AND GETDATE()

SELECT * FROM #GenericLeadStats

DROP TABLE #GenericLeadStats 

В SQL Server предложение SELECT INTO создает таблицу, которая еще не существует. Я оставляю это, но это не имеет смысла основано на том, что предоставлено.

2 голосов
/ 25 октября 2010

Как правило, базы данных хранятся на диске. Однако во всех современных операционных системах файлы после чтения часто кэшируются в памяти. Причина, по которой запрос выполняется медленно, заключается в том, что данные читаются с диска. После этого первого запроса большая часть данных (если не всех), необходимых для повторного выполнения запроса, кэшируется и не требует фактического чтения с диска (медленно). Через некоторое время, если компьютер используется для других целей или выполняются другие запросы, данные перемещаются из кэша, чтобы освободить место для новых данных, поэтому запрос будет снова замедлен, как только данные будут перечитаны с диска.

Вы должны быть уверены, что во всех столбцах в приведенном выше операторе were есть индекс. Я предполагаю, что это сделано? Если это так, то проверьте план запроса, чтобы увидеть, используются ли они. Наконец, если таблица довольно большая, вы можете рассмотреть ее разбиение, если это имеет смысл в вашей модели данных.

1 голос
/ 25 октября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...