记录一次SqlServer查询优化的过程(聚合索引的使用)

前提:

最近给人做一个程序,由于有导入导出操作,所以主键采用了GUID类型。

由于客户不能上网,SqlServer选择了2005,因为Sql2005比较小。。。

问题描述:

当数据量大于200w条后查询的效率直线下降。甚至到后来SqlServer连接超时引起了程序报错:CLR20r3。

问题分析:

这个当然是Sql查询时间太长惹的祸。

分页查询语句:

SELECT * FROM (  SELECT ROW_NUMBER() OVER (order by T.SortCode)AS Row, T.*  from TableA T  
WHERE DepartGUID = 'd4d22c04-6d15-4bad-b0f7-f8466eb371cc' ) TT
WHERE TT.Row between 1 and 100

在查询编辑器中执行会耗时48S。

解决过程:

当然是创建索引了。在where,groupby语句所涉及到的表字段都添加了非聚合索引,但是效率依旧,仍然是48s。

这下有些麻烦了,难道索引也解决不了问题,而且数据量也不大啊~!

直到看到这篇文章:SQLSERVER聚集索引和主键(Primary Key)的误区认识

因为聚合索引是唯一的,而且一般会设置在主键上。但是主键ID都是自动创建的,查询的时候一般不会涉及到,而且分页的时候更不是按照主键来分页的。所以需要取消主键的聚合索引并添加到了主要区分的字段上。

解决方案:

如何删除主键上的聚合索引?

如何在非主键上创建聚合索引?

参考了文章:SQL Server 关于聚集索引的操作

创建于主键上的聚集索引是不可以通过Drop等语句来删除的,要想删除位于主键上的聚集索引,我们可以通过先删除主键约束,这样将会自动删除主键上的聚集索引,然后在其他字段上创建聚集索引,最后在创建主键时将其修改为非聚集索引;

ALTER TABLE TableA DROP CONSTRAINT PK_TableA
CREATE CLUSTERED INDEX Index_IndexGUID ON TableA(IndexGUID)
ALTER TABLE TableA ADD CONSTRAINT PK_TableA PRIMARY KEY NONCLUSTERED(ItemGUID)
这样就解决了问题,现在再执行上述的分页查询基本不会耗时,1S以内,效率提高非常明显!


你可能感兴趣的:(Winform,APP,DataBase)