如何提高SQL Server 2008中的大表分页速度

问题描述:

我有一个名为Users的表,其中有1000万条记录。这是表结构:如何提高SQL Server 2008中的大表分页速度

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. 

enter image description here

任何人给我一些建议如何提高呼叫速度会升值。谢谢!

+0

我想你在强调执行计划中的错误。这就是说,聚集索引查找占用了你85%的时间。这里发生了什么?你还可以得到一些io统计数据,看看是否有任何锁争用? –

+0

@jtseng - 有趣的观察,但这只是成本模型的限制。对于具有1000万行的'CREATE TABLE T1(C INT PRIMARY KEY);'。 SQL Server提供的行数在100和120之间,行数在9700000和9700020之间,估计成本完全相同[见计划](http://i.stack.imgur.com/jYodX.png),尽管第二个必须处理比第一个更多的行。它假定扫描只需要100行,而不是实际的9,700,020,因此计划的这一部分显示的成本不正确。 [脚本重现](http://pastebin.com/FUS0JL8e) –

这看起来好像不会改变它的工作方式或进行某种预先计算。

用于查找页面上的UserId S上的指数是窄,因为它可以(叶子页面将包含只是UpdateTime和聚集索引的UsersID键,你可以通过改变datetime2赚了指数略窄但是这不会让一个显著的差别。你也可以查看这个指标并没有过多的碎片。

如果你有的UpdateTimeOrder索引顺序整数列,那么你可以只是做

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

但是,保持这样一个列以及并行的INSERTS/UPDATES/DELETES将是困难的。一个简单但不太有效的预先计算就是创建索引视图。

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页?

+0

:谢谢你的帮助! – user441222