2011-06-30 4 views
0

J'ai une procédure stockée qui gère le tri, le filtrage et la pagination (en utilisant Row_Number) et quelques trucs funky :) Le SP est exécuté sur une table avec ~ 140k lignes.Mauvaises performances SP à partir d'ASP.NET

Le tout fonctionne très bien et pour au moins les premières dizaines de pages est super rapide. Cependant, si j'essaie de naviguer vers des pages plus hautes (par exemple, aller à la dernière page de 10k), le tout s'arrêtera et entraînera une erreur de délai SQL.

Si je lance la même requête, en utilisant les mêmes parms à l'intérieur fenêtre de requête de gestionnaire de studio, la réponse est indépendamment instantanée du numéro de page je passe.

Au moment où il est le code de test qui lie simplement à un ASP: Datagrid dans .NET 3.5

Le SP ressemble à ceci:

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 '%'[email protected]+'%' 
    OR OrderNumber LIKE '%'[email protected]+'%' 
    OR [Description] LIKE '%'[email protected]+'%' 
    OR Client LIKE '%'[email protected]+'%')  
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 

Et il est appelé par

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

par exemple.

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

Quelqu'un peut-il faire la lumière sur ce qui pourrait être la cause de la différence spectaculaire des performances entre la fenêtre de requête SQL et une page asp.net l'exécution d'un ensemble de données?

+0

Désolé "WITH RECOMPILE" à propos de la mise en page, nouveau ici et ne savent pas comment faire le look de code purdy: -} – Rich

+0

vous pouvez également cross-post cette plus à la DBA StackExchange aussi. http://dba.stackexchange.com/ – Jordan

+0

@Jordan Merci pour le pointeur, je viens de m'inscrire là et posté. – Rich

Répondre

1

J'ai rencontré des problèmes similaires où le plan d'exécution sur les procédures stockées fonctionnera très bien pendant un certain temps, mais ensuite obtenir un nouveau plan parce que les options ont changé. Ainsi, il sera "optimisé" pour un cas, puis effectuera des "analyses de table" pour une autre option. Voici ce que j'ai essayé dans le passé:

  1. Ré-exécutez la procédure stockée pour calculer un nouveau plan d'exécution et ensuite garder un œil dessus.
  2. Décomposer la procédure stockée en procédures stockées distinctes de chaque option de sorte qu'elle puisse être optimisée, puis la procédure stockée globale appelle simplement chaque procédure stockée "optimisée". Apportez les enregistrements dans un objet, puis effectuez toute la "tromperie funky" dans le code, puis il vous donne la possibilité de "mettre en cache" les résultats.

Évidemment, les options 2 et 3 sont meilleures que l'option 1. Je suis honnêtement trouver l'option # 3 devient le meilleur pari dans la plupart des cas. Je viens d'avoir une autre option 4. Au lieu d'effectuer vos "sélections internes" en une seule requête, vous pouvez mettre les résultats de vos sélections internes dans des tables temporaires, puis JOIN sur ces résultats. Je pousserais toujours pour l'option # 3 si possible, mais je comprends que parfois vous juste devez continuer à travailler la procédure stockée jusqu'à ce que cela "fonctionne".

Bonne chance.

+0

Merci pour la réponse mon ami. J'ai déjà essayé de le démonter et j'ai toujours le même problème. La 'tricherie funky' est vraiment juste la partie KEYS au sommet, donc finalement rien de spécial. Je préférerais ne pas aller sur la route des tables temporaires si je peux l'éviter: -/ – Rich

+0

On dirait que vous étiez sur la bonne voie. Merci pour votre contribution :) – Rich

Questions connexes