Низкая производительность SP от ASP.NET - PullRequest
0 голосов
/ 30 июня 2011

У меня есть хранимая процедура, которая обрабатывает сортировку, фильтрацию и разбиение по страницам (используя Row_Number) и некоторые хитрые трюки :) SP работает с таблицей с ~ 140k строк.

Все это прекрасно работает, и, по крайней мере, первые несколько десятков страниц очень быстрые. Однако, если я пытаюсь перейти на более высокие страницы (например, перейти к последней странице 10 КБ), все это останавливается и приводит к ошибке тайм-аута SQL.

Если я выполняю тот же запрос, используя те же параметры в окне запроса менеджера студии, ответ мгновенный, независимо от номера страницы, которую я передаю.

На данный момент это тестовый код, который просто привязывается к ASP: Datagrid в .NET 3.5

ИП выглядит так:

BEGIN
WITH    Keys 
AS (
SELECT 
     TOP (@PageNumber * @PageSize) ROW_NUMBER() OVER (ORDER BY JobNumber DESC) as rn
    ,P1.jobNumber
    ,P1.CustID
    ,P1.DateIn
    ,P1.DateDue
    ,P1.DateOut
FROM vw_Jobs_List P1 
WHERE 
    (@CustomerID = 0 OR CustID = @CustomerID) AND 
    (JobNumber LIKE '%'+@FilterExpression+'%' 
  OR OrderNumber LIKE '%'+@FilterExpression+'%' 
  OR [Description] LIKE '%'+@FilterExpression+'%' 
  OR Client LIKE '%'+@FilterExpression+'%')    
ORDER BY P1.JobNumber DESC ),SelectedKeys
AS (
SELECT 
     TOP (@PageSize)SK.rn
    ,SK.JobNumber
    ,SK.CustID
    ,SK.DateIn
    ,SK.DateDue
    ,SK.DateOut 
FROM Keys SK 
WHERE SK.rn > ((@PageNumber-1) * @PageSize) 
ORDER BY SK.JobNumber DESC)

SELECT  
    SK.rn
   ,J.JobNumber
   ,J.Description
   ,J.Client
   ,SK.CustID
   ,OrderNumber
   ,CAST(DateAdd(d, -2, CAST(isnull(SK.DateIn,0) AS DateTime)) AS nvarchar) AS DateIn
   ,CAST(DateAdd(d, -2, CAST(isnull(SK.DateDue,0) AS DateTime)) AS nvarchar) AS DateDue 
   ,CAST(DateAdd(d, -2, CAST(isnull(SK.DateOut,0) AS DateTime)) AS nvarchar) AS DateOut
   ,Del_Method
   ,Ticket#
   ,InvoiceEmailed
   ,InvoicePrinted
   ,InvoiceExported
   ,InvoiceComplete
   ,JobStatus   
FROM SelectedKeys SK 
JOIN vw_Jobs_List J ON j.JobNumber=SK.JobNumber 
ORDER BY SK.JobNumber DESC
END

И он вызывается через

sp_jobs (PageNumber,PageSize,FilterExpression,OrderBy,CustomerID)

, например

sp_Jobs '13702','10','','JobNumberDESC','0'

Может ли кто-нибудь пролить свет на то, что может быть причиной разницы в производительности между окном SQL-запроса и страницей asp.net, выполняющей набор данных?

Ответы [ 2 ]

1 голос
/ 30 июня 2011

Проверьте опцию «С РЕКОМЕНДУЕМЫМ»

http://www.techrepublic.com/article/understanding-sql-servers-with-recompile-option/5662581

1 голос
/ 30 июня 2011

Я столкнулся с подобными проблемами, когда план выполнения хранимых процедур будет работать некоторое время, но затем получаю новый план, потому что параметры изменились. Таким образом, он будет «оптимизирован» для одного случая, а затем выполнит «сканирование таблицы» для другого варианта. Вот что я пробовал в прошлом:

  1. Повторно выполнить хранимую процедуру, чтобы рассчитать новый план выполнения, а затем следить за ним.
  2. Разбейте хранимую процедуру на отдельные хранимые процедуры для каждого параметра, чтобы ее можно было оптимизировать, а затем общая хранимая процедура просто вызывает каждую «оптимизированную» хранимую процедуру.
  3. Внесите записи в объект, а затем выполните весь «фанк-трюк» в коде, а затем он дает вам возможность «кэшировать» результаты.

Очевидно, что вариант № 2 и № 3 лучше, чем вариант № 1. Я честно нахожу, что вариант № 3 становится лучшей ставкой в ​​большинстве случаев.

У меня просто был другой вариант 4. Вы могли бы вместо того, чтобы выполнять «внутренние выборки» в одном запросе, вы могли бы поместить результаты ваших внутренних выборок во временные таблицы и затем присоединиться к этим результатам. Я бы по-прежнему настаивал на варианте №3, если это возможно, но я понимаю, что иногда вам просто нужно продолжать работать с хранимой процедурой, пока она не «заработает».

Удачи.

...