0

我有一张表Users,里面有 1000 万条记录。这是表结构:

CREATE TABLE [dbo].[Users](
    [UsersID] [int] IDENTITY(100000,1) NOT NULL,
    [LoginUsersName] [nvarchar](50) NOT NULL,
    [LoginUsersPwd] [nvarchar](50) NOT NULL,
    [Email] [nvarchar](80) NOT NULL,
    [IsEnable] [int] NOT NULL,
    [CreateTime] [datetime] NOT NULL,
    [LastLoginTime] [datetime] NOT NULL,
    [LastLoginIp] [nvarchar](50) NOT NULL,
    [UpdateTime] [datetime] NOT NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
    [UsersID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

UpdateTime我在列上有一个非聚集索引。

分页sql:

;WITH UserCTE AS (
   SELECT * FROM 
    (SELECT 
        ROW_NUMBER() OVER (ORDER BY UpdateTime DESC) AS row,UsersID as rec_id -- select primary key only
    FROM 
        dbo.Users WITH (NOLOCK)
    ) A WHERE row BETWEEN 9700000 AND 9700020
)
SELECT
   *
FROM
    dbo.Users WITH (NOLOCK) WHERE UsersID IN (SELECT UserCTE.rec_id FROM UserCTE)

上面的查询:

SQL Server parse and compile time: 
CPU time = 0 ms, elapsed time = 3 ms.
(21 row(s) affected)

SQL Server Execution Times:
CPU time = 2574 ms,  elapsed time = 3549 ms.

在此处输入图像描述

任何人给我一些关于如何提高分页速度的建议都会很感激。谢谢!

4

1 回答 1

4

在不改变它的工作方式或进行某种预先计算的情况下,这看起来和它一样好。

用于在页面上定位 s 的索引尽可能UserId窄(叶页将只包含区别。你也可以检查这个索引没有过多的碎片。UpdateTimeUsersIDdatetime2

如果您有一个索引的顺序整数列,UpdateTimeOrder那么您可以这样做

SELECT *
FROM dbo.Users
WHERE UpdateTimeOrder BETWEEN 9700000 AND 9700020

但是同时维护这样一个列和并发INSERTS//将是困难的。一种更简单但不太有效的预计算是创建索引视图。UPDATESDELETES

CREATE VIEW dbo.UserCount
WITH SCHEMABINDING
AS
SELECT COUNT_BIG(*) AS Count
FROM [dbo].[Users]

GO

CREATE UNIQUE CLUSTERED INDEX IX ON dbo.UserCount(Count)

然后检索预先计算的计数并调用不同的查询,ROW_NUMBER() OVER (ORDER BY UpdateTime ASC)如果在索引中查找超过一半的行(当然从计数中减去原始行号)

但是为什么你真的需要这个呢?你真的让人们访问第 485,000 页吗?

于 2013-06-29T17:21:25.720 回答