如何使用CTE调整存储过程分页

时间:2015-01-13 09:29:11

标签: sql-server performance stored-procedures

我有一个Store Proceduce使用CTE进行分页和过滤。当我用<测试时5000条记录,这家店跑得快。但是当我用20.000条记录进行测试时它非常低。

我的商店程序:

WITH Members  AS (SELECT * ,ROW_NUMBER() OVER (ORDER BY IssuesID DESC) AS RowNumber,Count(*) over () AS TotalRows  
    FROM (SELECT DISTINCT  
    A.IssuesID, 
    CASE WHEN dbo.func_HelpDesk_CheckEnterprise(A.CustomerID) = 1 
    THEN (SELECT Descriptions FROM SystemDefine WHERE Codes = '11' AND Types = 24) 
    ELSE H.Descriptions END AS SupportOptionName, 
    A.DueDate, 
    CAST(A.Title as nvarchar(4000)) Title,
    A.OrderNumber, 
    A.ProductID, 
    A.VariantID, 
    CAST(A.Description as nvarchar(4000)) as Description,
    A.Priority,
    A.CustomerID, 
    A.InternalID, 
    CONVERT(DateTime,CONVERT(varchar(12), A.CreatedDate)) CreatedDate, 
    A.AssignedTo, 
    A.IsReceiveMails,   
    A.IssueType, 
    A.TicketStatus, 
    A.AssignedToSupport, 
    A.IssueCategory, 
    A.SupportLevel,  
    A.ModifiedBy, 
    A.CreatedBy, 
    A.CaseOrigin, 
    A.Release, 
    A.LastContact, 
    A.Disposition, 
    A.SupportOption, 
    A.UseEmail,  
    D.SKU + E.SKUSuffix AS SKUProduct,    
        -- F.CreatedOn,  
    Case WHEN A.TicketStatus = 4 AND GetDate() > dateadd(dd,7,DueDate) 
    THEN 'Archived'  
    ELSE B.Descriptions END AS TicketStatusName, 
    C.Descriptions PriorityName, 
    Case 
    WHEN A.IssueType=1  THEN 'T' 
    WHEN A.IssueType=2 THEN 'Q' 
    ELSE 'Trial' END IssueTypeDesc, 
    dbo.SplitData(D.SKU,'.',1) SKU, 
    G.FirstName + ' ' + G.LastName As CustomerName,   
    CASE 
    WHEN LEN(A.Title) > 40 THEN LEFT(A.Title,40) + ' . . .' 
    ELSE A.Title END ShortTitle,  
    I.Descriptions as CaseReasonName, 
    G.Email, 
    Cast(A.DescriptionToText as nvarchar(4000)) DescriptionToText 
    FROM Helpdesk_IssuesList A 
        LEFT JOIN Customer G ON A.CustomerID = G.CustomerID   
        LEFT JOIN SystemDefine B ON A.TicketStatus = B.Codes AND B.Types = 15  
        LEFT JOIN SystemDefine C ON A.Priority = C.Codes AND C.Types = 16  
        LEFT JOIN SystemDefine I ON A.IssueCategory = I.Codes AND I.Types = 17  
        LEFT JOIN SystemDefine H ON A.SupportOption = H.Codes AND H.Types = 24  
        LEFT JOIN Product D ON D.ProductID = A.ProductID  
        LEFT JOIN ProductVariant E ON E.VariantID = A.VariantID  
        LEFT JOIN Orders_ShoppingCart F ON F.OrderNumber = A.OrderNumber AND F.ProductID = A.ProductID AND F.VariantID = A.VariantID     
    WHERE ISNULL(A.Deleted,0) = 0  
    AND CreatedDate BETWEEN '01/01/1999' AND '01/02/2099' 
    AND (ISNULL(A.IssueType,0) IN (0,1,2,3)) ) A WHERE 1=1)  
    SELECT * FROM Members A  WHERE RowNumber BETWEEN 1 AND 15 ORDER BY RowNumber ASC;
  • 使用< 5000条记录=>来自 2s - >的 4S
  • 20.000+条记录=> 6s +

所以当我在网站上绑定网格时,它会丢失大约10秒。

这是我的执行计划:

https://www.fshare.vn/file/C36AO9ZV74NO

任何人都可以帮助我吗?请。

更新

我上传了我的sql计划的一些图片,但它太大了所以我只拍摄了很多费用的部分。

enter image description here

enter image description here

更新了查询和执行计划:

WITH Members  AS ( SELECT   ROW_NUMBER() OVER (ORDER BY 
            (CASE WHEN dbo.func_HelpDesk_CheckEnterprise(A.CustomerID) = 1 
            THEN isEnterprise 
            ELSE notEnterprise END) DESC) AS RowNumber,Count(*) over () AS TotalRows ,IssuesID,isEnterprise,notEnterprise,DueDate,Title,OrderNumber,ProductID,VariantID,[Description],[Priority],CustomerID,InternalID,CreatedDate,AssignedTo,IsReceiveMails,IssueType,TicketStatus,AssignedToSupport,IssueCategory,SupportLevel,ModifiedBy,CreatedBy,CaseOrigin,Release,LastContact,Disposition,SupportOption,UseEmail,TicketStatusName,PriorityName,IssueTypeDesc,SKU,FirstName,LastName,CaseReasonName,Email,DescriptionToText FROM (SELECT  A.IssuesID,(SELECT Descriptions FROM SystemDefine WHERE Codes = '11' AND Types = 24) as isEnterprise,H.Descriptions as notEnterprise,
            --CASE WHEN dbo.func_HelpDesk_CheckEnterprise(A.CustomerID) = 1 
            --THEN (SELECT Descriptions FROM SystemDefine WHERE Codes = '11' AND Types = 24) 
            --ELSE H.Descriptions END AS SupportOptionName, 
        A.DueDate, CAST(A.Title as nvarchar(4000)) Title, A.OrderNumber, 
        A.ProductID, A.VariantID, CAST(A.Description as nvarchar(4000)) as Description, A.Priority,  
        A.CustomerID, A.InternalID, CONVERT(DateTime,CONVERT(varchar(12), A.CreatedDate)) CreatedDate, A.AssignedTo, A.IsReceiveMails,   
        A.IssueType, A.TicketStatus, A.AssignedToSupport, A.IssueCategory, A.SupportLevel,  
        A.ModifiedBy, A.CreatedBy, A.CaseOrigin, A.Release, A.LastContact, A.Disposition, A.SupportOption, A.UseEmail,    
        -- F.CreatedOn,  
        Case WHEN A.TicketStatus = 4 AND GetDate() > dateadd(dd,7,DueDate) THEN 'Archived'  
        ELSE B.Descriptions END AS TicketStatusName, 
        C.Descriptions PriorityName, Case WHEN A.IssueType=1 THEN 'T' WHEN A.IssueType=2 THEN 'Q' ELSE 'Trial' END IssueTypeDesc, 
        SKU, G.FirstName, G.LastName ,   CASE WHEN LEN(A.Title) > 40 THEN LEFT(A.Title,40) + ' . . .' ELSE A.Title END ShortTitle,  
        I.Descriptions CaseReasonName, G.Email, Cast(A.DescriptionToText as nvarchar(4000)) DescriptionToText FROM Helpdesk_IssuesList A 
        LEFT JOIN SystemDefine B ON A.TicketStatus = B.Codes AND B.Types = 15  
        LEFT JOIN SystemDefine C ON A.Priority = C.Codes AND C.Types = 16  
        LEFT JOIN SystemDefine I ON A.IssueCategory = I.Codes AND I.Types = 17  
        LEFT JOIN SystemDefine H ON A.SupportOption = H.Codes AND H.Types = 24  
        LEFT JOIN Product D ON D.ProductID = A.ProductID  
        LEFT JOIN Customer G ON A.CustomerID = G.CustomerID  
        WHERE ISNULL(A.Deleted,0) = 0  AND CreatedDate BETWEEN '01/01/1999' AND '01/02/2099' 
        AND (ISNULL(A.IssueType,0) IN (0,1,2,3)) ) A WHERE 1=1)  
        SELECT RowNumber,TotalRows,IssuesID,
        CASE WHEN dbo.func_HelpDesk_CheckEnterprise(A.CustomerID) = 1 
            THEN isEnterprise
            ELSE notEnterprise END as SupportOptionName
        ,DueDate,Title,OrderNumber,ProductID,VariantID,[Description],
        [Priority],CustomerID,InternalID,CreatedDate,AssignedTo,IsReceiveMails,
        IssueType,TicketStatus,AssignedToSupport,IssueCategory,
        SupportLevel,ModifiedBy,CreatedBy,CaseOrigin,Release,LastContact,
        Disposition,SupportOption,UseEmail,TicketStatusName,PriorityName,
        IssueTypeDesc,dbo.SplitData(SKU,'.',1) SKU,FirstName + ' ' + LastName as CustomerName,
        CASE WHEN LEN(Title) > 40 THEN LEFT(Title,40) + ' . . .' ELSE A.Title END ShortTitle, CaseReasonName,Email,DescriptionToText 
        FROM  Members A  
        WHERE     RowNumber BETWEEN 1 AND 25 ORDER BY RowNumber ASC 

enter image description here

新查询的结果:

  • 以20k +记录提高绩效: 6s + => 2s> 3S

使我的查询变慢的主要原因是加入表ProductVariant。当我删除此连接时,我的查询比以前运行得更快。第二个原因是在第一个SELECT上使用函数。我认为这些函数循环遍历所有记录。所以我将它移动到最后一个SELECT,它只在分页后得到几条记录。

p / s:对不起我的英语。我的英语不好,所以也许你很难理解我的意思。

0 个答案:

没有答案