使用SQL存储过程通过分页和自定义搜索查询百万条记录

时间:2017-02-23 09:09:17

标签: asp.net sql-server stored-procedures gridview

我需要帮助优化此查询,以便从企业中检索产品列表。此查询仅使用您在下面看到的特定参数来提供数据集。大约40,000种产品运行大约需要6-9秒,一次只能生产10种产品,但我需要加快速度。

我执行此操作:

EXEC [GetProducts] @StartRowIndex=0, @MaximumRows=10,
@SortedBy='ProductName', @SortedIn='DESC', @CategoryID=0,
@CategoryIDPath=N'''1|%''', @SearchText='ALL', @SearchSQL=N'', @CreatedByUser=0

以下是完整查询:

ALTER PROCEDURE [GetProducts] (
   @StartRowIndex int,
   @MaximumRows int,
   @SortedBy nvarchar(20),
   @SortedIn nvarchar(6),
   @CategoryID int,
   @CategoryIDPath nvarchar(500),
   @SearchText nvarchar(255),
   @SearchSQL nvarchar(MAX),
   @CreatedByUser int
)

as
BEGIN

--get correct Sorted By
DECLARE @strSortedBy nvarchar(300)
SET @strSortedBy = 
    (CASE
        WHEN (@SortedBy = 'CreatedDate') THEN 'Products.CreatedDate ' + @SortedIn
        WHEN (@SortedBy = 'Views') THEN 'Products.Views ' + @SortedIn
        ELSE 'Products.ProductName ' + @SortedIn
     END)

--check if you are filtering by Category START
DECLARE @FilterByCategoryID nvarchar(250)
IF (@CategoryID > 0)
    BEGIN
        SET @FilterByCategoryID = 'AND Products.CategoryID = ' + cast(@CategoryID as nvarchar(5))
    END
else
    BEGIN
        IF (@CategoryIDPath <> '') --show category features first then the most recent by default
        BEGIN
            SET @FilterByCategoryID = 'AND Products.CategoryIDPath LIKE ' + @CategoryIDPath
        END
    else
        BEGIN
            SET @FilterByCategoryID = ''
        END
    END
--check if you are filtering by Category END

--this option is used when you are searching by category only START
IF (@SearchText <> '')
    BEGIN
        IF @SearchSQL = 'ALL'
            BEGIN
                SET @SearchSQL = ''
            END
    END
else
    BEGIN
        SET @SearchSQL = ''
    END
--this option is used when you are searching by category only END

--check if you are filtering by CreatedByUser START
DECLARE @FilterByCreatedByUser nvarchar(250)
IF (@CreatedByUser > 0)
    BEGIN
        SET @FilterByCreatedByUser = 'AND Products.CreatedByUser = ' + cast(@CreatedByUser as nvarchar(10))
    END
else
    BEGIN
        SET @FilterByCreatedByUser = ''
    END
--check if you are filtering by CreatedByUser END

DECLARE @MaximumRow int
SET @MaximumRow = @startRowIndex + @maximumRows

    exec('SELECT 
        RowRank
        ,Products.ItemID
        ,Products.ProductName
        ,Products.Description
        ,Products.CategoryID
        ,Products.CategoryIDPath
        ,Products.FileName      
        ,Products.CategoryName

        ,Businesses.BusinessName
        ,Businesses.Country

        ,Products.TotalCount
    FROM
        (
        SELECT
            ROW_NUMBER() OVER(ORDER BY ' + @strSortedBy + ') AS RowRank
            ,COUNT(*) OVER() AS TotalCount
            ,Products.*         
        FROM
            Products
                INNER JOIN Businesses
                    ON Products.CreatedByUser = Businesses.CreatedByUser
                    AND Businesses.Published <> 0 
                    AND (Businesses.[ExpireDate] >= GetDate() or Businesses.[ExpireDate] is null)   
        WHERE
            Products.Published <> 0
            AND (Products.[ExpireDate] >= GetDate() OR Products.[ExpireDate] is null)
            AND Products.ItemType = ''Classifieds''
            ' + @FilterByCategoryID + '
            ' + @FilterByCreatedByUser + '
            ' + @SearchSQL + '
        ) AS Products
            INNER JOIN Businesses
                ON Products.CreatedByUser = Businesses.CreatedByUser
                AND Businesses.Published <> 0 
                AND (Businesses.[ExpireDate] >= GetDate() or Businesses.[ExpireDate] is null)                   
    WHERE 
        RowRank > ' + @startRowIndex + ' AND RowRank <= ' + @MaximumRow + '

    ORDER BY ' + @strSortedBy)

END

0 个答案:

没有答案