繁体   English   中英

如何正确索引具有2500万行的SQL Server表

[英]How to properly index SQL Server table with 25 million rows

我在SQL Server 2008 R2中创建了一个表,如下所示:

CREATE TABLE [dbo].[7And11SidedDiceGame]
(
    [Dice11Sides] [INT] NULL,
    [Dice7Sides] [INT] NULL,
    [WhoWon] [INT] NULL
)

我添加了以下索引:

CREATE NONCLUSTERED INDEX [idxWhoWon] 
ON [dbo].[7And11SidedDiceGame] ([WhoWon] ASC)

然后,我创建了一个WHILE循环,以插入2500万随机生成的行,以对结果进行统计分析。

一旦我优化了Insert函数(在循环之前和之后使用BEGIN TRAN和COMMIT TRAN),While循环就可以正常运行了。 但是,分析数据需要很长时间。 例如:使用以下语句大约需要4分钟才能执行:

DECLARE @TotalRows real

SELECT @TotalRows = COUNT(*) 
FROM [test].[dbo].[7And11SidedDiceGame]

PRINT REPLACE(CONVERT(VARCHAR, CAST(@TotalRows AS money), 1),'.00','') 

SELECT 
    WhoWon, COUNT(WhoWon) AS Total,  
    ((COUNT(WhoWon) * 100) / @TotalRows) AS PercentWinner
FROM 
    [test].[dbo].[7And11SidedDiceGame]
GROUP BY 
    WhoWon

我的问题是如何更好地索引表以加快数据检索速度? 还是我需要以其他方式处理数据提取?

我认为您在这里不能做很多事情。

查询必须从索引中读取所有25M行以对其进行计数。 但是,2500万行不是很多,我希望在现代硬件上花费不到4分钟。 读取的数据只有100MB(好的,实际上更多的是200MB,但从磁盘读取200MB的时间应该不需要4分钟)。

服务器是否负担沉重? 该表中有很多插入物吗?

您可以通过将表中的WhoWon列定义为NOT NULL进行小幅改进。 您真的有NULL值吗?

然后在查询中使用COUNT(*)代替count(WhoWon)

如果此查询经常运行,但是表中的数据变化不是太频繁,则可以创建一个索引视图,该视图本质上会具体化/缓存/预先计算这些计数,因此从该视图运行的查询将会很多快点。

您可能可以通过使用窗口功能来加快速度:

SELECT WhoWon, count(*) AS Total,   
       count(*) * 100.0 / sum(count(*)) over ()  as PercentWinner
FROM [test].[dbo].[7And11SidedDiceGame]
GROUP BY WhoWon;

这没有提供单独的print语句。

为了提高性能,请尝试在(WhoWon)上建立索引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM