【自己】索引的触发

select, join 的条件, join后面的and,where , 任何判断条件,等于、不等于 等等。

用的多的字段都要索引。 in左边触发索引,右表不,因为有in(里面的一般是小数据)

not in 左右都不触发

exists 左边不触发, 右边触发

not exists左右触发

 

<mgrobjid,dictionary<id,property>正确的建立索引
 
       首先,我们需要明白几个索引的要点:
 
1.索引之后,按索引字段重复最少的来排序,会达到最优的效果。以我们的表来说,如果建立了No的聚集索引,把No放在where子句的第一位是最佳的,其次是Id,然后是MgrObjId,最后是时间,时间索引如果表是一个小时的,最好不要用

2.where子句的顺序决定了查询分析器是否使用索引来查询。比如建立了MgrObjId和Id的索引,那么where MgrObjId='' and Id='' and Dtime=''就会采用索引查找,而where Dtime='' and MgrObjId='' and Id=''则不一定会采用索引查找。

3.把非索引列的结果列放在包含列中。因为我们条件是MgrObjId和Id以及Dtime,因此返回结果中只需包含Dtime和Value即可,因此把Dtime和Value放在包含列中,返回的索引结果就有这个值,不用再查物理表,可以达到最优的速度。

       跟上述几点原则,我们建立以下的索引:CREATE NONCLUSTERED INDEX Idx_His20141008 ON dbo.his20141008(MgrObjId,Id) 
INCLUDE(Value,Dtime)
 
       耗费时间为:6分多钟,索引大小为903M。
 
       我们看看预估计划:

 
       可以看到,这里完全使用了索引,没有额外的消耗。而实际执行的结果,1秒都不到,竟然不用一秒就在1100w的记录中把结果筛选了出来!!帅呆了!!
 
怎么应用索引?
 
       既然写入完成了、读取完成了,怎么结合呢?我们可以把一个小时之前的数据建立索引,当前一个小时的数据就不建立索引。也就是,不要再创建表的时候建立索引!!
 
还能怎么优化
 
       可以尝试读写分离,写两个库,一个是实时库,一个是只读库。一个小时内的数据查询实时库,一个小时之前的数据查询只读库;只读库定时存储,然后建立索引;超过一个星期的数据,进行分析处理再存储。这样,无论查询什么时间段的数据,都能够正确处理了——一个小时之内的查询实时库,一个小时到一个星期内的查询只读库,一个星期之前的查询报表库。
 
       如果不需要物理分表,则在只读库中,定时重建索引即可。
 

总结

 
       如何在SQLServer中处理亿万级别的数据(历史数据),可以按以下方面进行:
 
       去掉表的所有索引

       用SqlBulkCopy进行插入

       分表或者分区,减少每个表的数据总量

       在某个表完全写完之后再建立索引

       正确的指定索引字段

       把需要用到的字段放到包含索引中(在返回的索引中就包含了一切)

       查询的时候只返回所需的字段
 
 
posted @   阿玛  阅读(522)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示