探究SQL添加非聚集索引,性能提高几十倍之谜
上周,技术支持反映:客户的一个查询操作需要耗时6.1min左右,在跟进代码后,简化了数据库的查询后仍然收效甚微。后来,技术总监分析了sql后,给其中的一个表添加的一个非聚集索引(三个字段)后,同样的查询操作耗时只需要6s-7s。
原sql大概需要左联left join 十几个 ,left join前后的两个表又是笛卡尔积。因此,只要其中有一个表的数据有很多,那么sql需要检索的数据集会无比巨大。根据where后面过滤的字段(至少两个字段)添加非聚集索引后,数据库会自动复制一份数据,然后sql查询时会去这份复制的数据检索,这样就大大地减少了数据库响应的时间。那么是否非聚集索引越多越好呢?通常来讲,一个表只能有一个聚集索引,但可以有多个非聚集索引。而数据库索引主要目的就是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 。但这并不意味着索引(非聚集索引)越多越好。恰当的索引设计会显著提高性能,反之会得不偿失。当我们的技术支持给客户设计索引时,查询时间仍然没有如期提高。这就是非聚集索引设计不恰当的例子。因为那三个字段(前面提到)中包含一个字段:现场时间,而这个字段是会动态变化的,客户查询操作的一个过滤条件就是时间,所以并没有如期生效,因为sql查询时没有命中这个复制的数据集。所以当减少这个字段时,查询时间又回到6s-7s之间,命中率显著提高。
此外,非聚集索引的增加会增加硬盘(或内存)的开销,世上没有一举两得事情,所以权衡利弊恰当地设计索引尤为重要。
本人博客园已停止更新,请大家浏览 https://jinuss.github.io/blog