原来分析为啥慢的原因分析错误,不是因为索引大的原因,而是错误的使用聚合索引,造成查询频繁的访问数据,进而磁盘I/O很大。
这里错误的使用聚合索引,就是因为在聚合索引中,错误的把Time字段放到前面了。
“索引本身就很大了,大的要遍历这个索引就要频繁的磁盘I/O” 这句话是错误的,对指出这句话错误的色盲 、文盲 、李颖 深表感谢。 以下是修改过的原因分析。
最近连续三、四天,CSDN的登录一直不正常,白天人多的时候,经常会登录超时。为这个问题苦恼了好几天,不知道头发都掉了几根。^&^.
昨天和今天,通过做实验和咨询CSDN几个SQL Server版的大斑竹,才搞清楚是由于当初,想当然的以为聚集索引的效率要比非聚集索引的效率高,错误的使用了聚合索引,而修改了登录日志表中的索引造成的。
CSDN 存在这如下结构的登录日志数据表(安全起见,我修改了表名、字段名)
CREATE TABLE [dbo].[Table1] (
[CSDNUserID] [int] NOT NULL ,
[Time] [smalldatetime] NOT NULL ,
[IP] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ) ON [PRIMARY]
而登陆的时候存在一个判断三分钟内登录次数不能超过5次的存储过程。其核心SQL如下:
if ((select count( * ) as num from Table1 where abs(datediff(minute,Time,getdate()))<3 and CSDNUserID = @DBUserID) >= 5 )
最近这几天新建的索引是由CSDNUserID和Time组成的聚集索引。(Time靠前的聚合索引)由于最近定期清理登录日志不是很及时,这个表非常大,达到600万以上的数量级。这个索引查询就会非常非常的巨大。上面的SQL语句,在执行的时候,磁盘I/0 ,CPU 的占用就会巨大。进而造成这几天CSDN登录频繁超时。
如果把聚合索引修改顺序,把UserID 靠前,结果就不一样了,两个的速度差别是近千次的差别。
如果修改为不用聚集索引,只在CSDNUserID上建立非聚集索引。这时候的查询速度跟正确的使用聚合索引的时候速度差很小,比起错误的使用聚合索引时候速度差,仍然是近千倍。
当然,如果能定期的清理日志表,速度要比现在要快很多,如果这个日志表足够的小,使用聚集索引反而要非聚集索引要快很多。
如果只是在这里判断三分钟内登录次数不超过5次,这里的判断语句,如果使用正确的聚集索引的。速度是会提高的,当时提高的等次不是特别的大。
另外,在处理这个问题的时候,向邹建学到很多有用的东西,SQL查询分析器一些以前没有注意到的功能在这次查原因中用到,非常方便。
比如:
1、查询分析器中可以方便的看到一个表、存储过程依赖于那些表、存储过程。
2、查询分析器可以分析一个SQL 语句的计划执行情况,从这里可以方便的进行SQL的性能优化。