首页 > 解决方案 > 多个左连接的 SQL 分页非常慢

问题描述

我有一个存储过程,我必须使用分页来获取网格的记录。该查询适用于单个表,但是一旦我开始添加左连接,事情就会变得越来越慢。对第 10 页记录的简单查询对于单个表需要 1 秒,但对于 2 个左连接需要 3 分钟。所有表都有索引。有没有更好更有效的方法来用左连接写这个?也许是一个子查询?

DECLARE 
    @Declare PersonNumber XML,
    @PageSize INT = 10, 
    @PageNum  INT = 1;

WITH TempResult AS
(
    SELECT ID, Name
    FROM Table T
    LEFT JOIN Table A ON a.Id = T.Id
    LEFT JOIN Table B ON B.Id = A.Id 
                      AND B.Date = A.DATE 
                      AND B.IsActive = 1
), TempCount AS 
(
    SELECT COUNT(*) AS MaxRows 
    FROM TempResult
)
SELECT *
FROM TempResult, TempCount
ORDER BY TempResult.Name
    OFFSET (@PageNum - 1) * @PageSize ROWS
    FETCH NEXT @PageSize ROWS ONLY

我需要的列已编入索引。

标签: sql-serverpaginationleft-joinssms-2016

解决方案


有时查询过于复杂,无法以最佳方式执行引擎。您可以尝试为引擎提供更简单的查询和更好的提示,以便顺利工作。

所以,在这种情况下:

  1. 简化查询:

    CREATE TABLE #TempResult
    (
        [ID] INT
       ,[Name] NVARCHAR(128)
    );
    
    INSERT INTO #TempResult ([ID], Name])
    SELECT ID, Name
    FROM Table T
    LEFT JOIN Table A ON a.Id = T.Id
    LEFT JOIN Table B ON B.Id = A.Id 
                      AND B.Date = A.DATE 
                      AND B.IsActive = 1;
    
    DECLARE @MaxRows INT;
    
    SELECT @MaxRows = COUNT(*)
    FROM #TempResult;
    
    SELECT *
          ,@MaxRows AS [MaxRows]
    FROM #TempResult
    ORDER BY Name
    OFFSET (@PageNum - 1) * @PageSize ROWS
    FETCH NEXT @PageSize ROWS ONLY;
    
  2. 然后,如果使用 的初始查询LEFT JOIN很慢,请尝试对其进行优化。例如,您可以添加检查用于提取数据的索引(如果存在) - 您可以添加过滤索引以优化查询。

  3. 如果提取并返回其他列 - 例如名称、邮件、地址或其他内容,请不要提取它们。仅获取ID您要订购的 s 和列。执行分页并使用结果ID获取其他详细信息。

推荐阅读