У меня возникла неустойчивая проблема с хранимой процедурой SQL, которая извлекает продукты из SQL dB. У нас около 3500 активных пользователей, и, как правило, около 15-30 пользователей вошли в систему сразу, используя эту процедуру. За прошлую неделю у меня были сообщения с истекшим временем ожидания, например:Истекший период ожидания SQL - прерывистая проблема
System.Data.SqlClient.SqlException: время ожидания истекло. Период ожидания истекает до завершения операции или сервер не отвечает. в System.Data.SqlClient.SqlConnection.OnError (исключение SqlException, Boolean breakConnection) в System.Data.SqlClient.SqlInternalConnection.OnError (исключение исключений SqlException, логическое breakConnection) в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning (TdsParserStateObject stateObj) в системе .Data.SqlClient.TdsParser.Run (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) в System.Data.SqlClient.SqlDataReader.ConsumeMetaData() в System.Data.SqlClient.SqlDataReader.get_MetaData() в системе .Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) в System.Data.SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) в System.Data.SqlClient.SqlCommand. RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String meth od, результат DbAsyncResult) в System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, метод String) в System.Data.SqlClient.SqlCommand.ExecuteReader (поведение CommandBehavior, метод String) в System.Data. SqlClient.SqlCommand.ExecuteDbDataReader (поведение CommandBehavior) в System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader (поведение CommandBehavior) в System.Data.Common.DbDataAdapter.FillInternal (DataSet dataset, DataTable [] datatables, Int32 startRecord , Int32 maxRecords, String srcTable, команда IDbCommand, поведение CommandBehavior) в System.Data.Common.DbDataAdapter.Fill (DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, команда IDbCommand, поведение CommandBehavior) в System.Data.Common.DbDataAdapter .Fill (DataSet dataSet, String srcTable) при разрешении .PopulateRegularLineList (Int32 PageIndex) в e: \ Веб-сайты \
SP возвращает 12 продуктов за раз (или больше, если выбрано раскрывающееся поле), и выполняется быстро, когда я запускаю его вручную. Это произошло, возможно, 20 раз за прошедшую неделю с разными пользователями в разное время суток, и поэтому я не смог воссоздать ошибку при запуске процедуры или использовании тестовых учетных записей для просмотра сайта. Я где-то читал, что добавление NOLOCK или увеличение тайм-аута команды могут его исправить, но это только быстрое закрытие, а не решение основной проблемы (не говоря уже о плохих данных NOLOCK).
Часть SQL, которая отображает продукт здесь:
INSERT INTO @Products (WWHEAD, WWPROD, WWDESC, CTNQTY, PRC1, PRC4, [FILENAME], DPQIS, QTYL, FileReference, LineId, Price5, PriceGroup, Dimensions)
(SELECT A.WWHEAD, A.WWPROD, A.WWDESC, A.CTNQTY,
CASE WHEN @IsPrice5 = 5 THEN LTRIM(RTRIM(A.Price5)) ELSE LTRIM(RTRIM(A.PRC1)) END,
CASE WHEN @IsPrice5 = 5 THEN A.Price5 ELSE A.PRC4 END,
[FILENAME],
(CAST((DPQIS-DPALOC) AS INT)),
D.QTY,
'WebImage',
LineId,
CASE WHEN @IsPrice5 = 5 OR A.Price5 = A.PRC4 THEN NULL ELSE A.PRICE5 END,
LTRIM(RTRIM(PG.PriceCode)) + ' ' + LTRIM(RTRIM(PG.GroupDesc)) + ' ' + LTRIM(RTRIM(PG.DiscDesc)),
Dimensions
FROM PRODUCTS A
INNER JOIN STOCK C ON A.WWPROD = C.DPPROD AND DPDEPO = 'CH'
INNER JOIN PROD_COPY W ON A.WWPROD = W.WWPROD
INNER JOIN PRODGRP PD ON PD.GPNUM = W.WWPRGP
LEFT OUTER JOIN ORDERS D ON D.OrderID = @OrdId AND A.WWPROD = D.ProdCode
LEFT OUTER JOIN PRGRP PG ON A.WWPCGP = PG.PriceCode
LEFT OUTER JOIN PRODALT_GRP X ON X.ProdCode = A.WWPROD
WHERE A.WWBONS = 'B'
AND A.WSID = 'WS'
AND (LTRIM(RTRIM(A.WWHEAD)) = LTRIM(RTRIM(@CatHead)) OR ISNULL(@CatHead, '0') = '0')
AND (LTRIM(RTRIM(A.WWSBHD)) = LTRIM(RTRIM(@CatSub)) OR ISNULL(@CatSub, '0') = '0')
AND (LEFT(LTRIM(RTRIM(A.WWPRGP)), 2) = LTRIM(RTRIM(@BrandT1)) OR ISNULL(@BrandT1, '0') = '0')
AND (LTRIM(RTRIM(A.GRPTR2)) = LTRIM(RTRIM(@BrandT2)) OR ISNULL(@BrandT2, '0') = '0')
AND (LTRIM(RTRIM(A.GRPTR3)) = LTRIM(RTRIM(@BrandT3)) OR ISNULL(@BrandT3, '0') = '0')
AND X.AltGroupCode = @ProductFilter
AND A.PRC1 BETWEEN @MinValue AND @MaxValue
AND A.WWHEAD <> 'B20'
AND (A.WWDESC Like ('%' + @SearchString + '%') OR A.WWPROD LIKE ('%' + @SearchString + '%')
OR A.WWPROD IN (SELECT Prodcode FROM WDS..Prod_Keywords INNER JOIN WDS..Keywords ON KeyID = KeywordID WHERE Keyword LIKE ('%' + @SearchString + '%')))
AND A.WWBRN NOT IN (SELECT * from WDS.dbo.f_BrandExclusionList(@WebUserName, NULL))
AND CAST(CASE WHEN NDATMM = '' THEN '01' ELSE NDATMM END + '-'
+ CASE WHEN NDATDD = '' THEN '01' ELSE NDATDD END + '-'
+ CASE WHEN NDATYY = '' THEN '1900' ELSE NDATYY END AS DATETIME) BETWEEN @threemonths AND GETDATE()
GROUP BY PD.GPSORT, A.WWHEAD, A.WWPROD, A.WWDESC, A.CTNQTY, A.PRC1, A.PRC4, [FILENAME], C.DPQIS, C.DPALOC, D.QTY,
LineId, A.Price5, PG.PriceCode, PG.GroupDesc, PG.DiscDesc, A.WWSBHD, A.WWBRN,
A.GRPTR2, A.GRPTR3, A.WWSORT, A.WWPCGP, Dimensions
HAVING ((A.PRC1 > 20.00 AND ((DPQIS-DPALOC) > 2)) OR (A.PRC1 <= 20.00 AND ((DPQIS-DPALOC) > 8))))
ORDER BY PD.GPSORT, A.WWBRN, A.GRPTR2, A.GRPTR3, A.WWPCGP DESC, A.WWHEAD, A.WWSBHD, A.WWSORT, A.WWPROD
Любые идеи? Заранее спасибо.
Здравствуйте, я добавил код SQL к исходному вопросу. благодаря – odinel