数据库索引、优化
参考地址:
如何看MS SQLSERVER数据库的执行计划https://blog.csdn.net/luoyanqing119/article/details/17022649
SQLserver索引的原理和应用https://www.cnblogs.com/knowledgesea/p/3672099.html
聚集索引和非聚集索引https://www.cnblogs.com/aspnethot/articles/1504082.html
数据库SQL优化大总结之 百万级数据库优化方案https://www.cnblogs.com/yunfeifei/p/3850440.html
数据库优化之程序操作优化https://www.cnblogs.com/AK2012/archive/2012/12/28/2012-122803.html
为什么不建议用select *?https://blog.csdn.net/u013240038/article/details/90731874
上图中,数据库执行一个T-SQL发生的事,了解一下数据库的构成以及功能。
执行计划:
可以缓存,存储过程/参数化查询
select * from User where id=1
select * from User where id=2
select * from User where id=@id
数据是什么?
数据库就是把东西有序放好,还能随时找到的一个工具。应用程序,有序的数据管理,数据在硬盘上(持久化,唯一的,多线程操作需要加锁,速度慢,可以SSD加快速度)。char nvarchar字段最长是8kb。
聚集索引
举个例子,在图书馆中,就是书多。图书馆是怎么分类的呢?文学、武侠、IT.....每个类别还有很多书啊,就按照首字母排序。新华字典文字都是按照字母排序的。聚集索引也叫聚簇索引,把数据有序的拜访,物理排序,找字母a开头,找时间范围的。。。
SQLserver自增int,默认聚集索引,所以查询不排序,就是Id排序。换聚集索引很耗时,很多的硬盘操作,生产环境需要谨慎。聚集索引只有一个,但是生成聚集索引的可以有多个列。一般是自增主键/创建时间/价格。因为数据物理排序了,所以查询快,非常适合大于、小于、between order by。
聚集索引速度大于非聚集索引
非聚集索引
在新华字典中,偏旁部首查找汉子---找页码----看详情。图书馆电子查找,输入名字---楼层----书架---层。
特点:重复存储值和路径,体积小一些,所以查找快一些,快速定位,直达目标。不影响数据的物理排序,但是会重复存储一个数据和位置。
找数据:先找索引----快速定位-----拿到数据,查找快,但是有维护的索引的成本,请小心。
非聚集索引可以有很多个,好像最多个255个,每个索引也可以有很多个字段,建议索引不要超过10个。适合经常查询的字段。非聚集索引不能运算,不能like'% %',也不能where Id-1>10。like 'a%'这个是可以用非聚集索引的。
建议索引的原则/建议:
1、主键是必须建立索引的(推荐数值主键,性能最高)
2、外键也要索引,join能提升性能
3、经常查询的字段建立索引
4、经常在where里面的也要建立索引
5、order by 、group by、distinct
6、聚合运算/where条件时,先索引字段
不需要建立索引的:
1、基本不怎么查询的
2、重复值比较伛的
3、text/image不要索引
4、索引不要太多了
还有其他的索引,主XML索引、辅助XML索引、空间索引、非聚集Columnstore索引(数量超过千万的时间建立的索引,先出的一个东西吧)
执行计划:
提交SQL语句,数据库查询优化器,经过分析生成,指定多个查询方式,从中算则使用资源最少的,数控制定执行计划是按照使用资源最少,而不是时间最短。
1、Table Scan 全表扫描性能最差
2、Cluster Index Scan (聚集索引的扫描) 性能最差,同上,虽然有聚集索引,其实也是全表扫描
3、Index Seek(NonClustered)(索引查找) 性能非常高
4、Index Scan 先Index 再扫描
5、Cluster Index Seek 性能最高
常规的SQL优化建议
1、对列的计算,任何形式都要避免
2、in 查询 or 查询索引会失效,可能是拆分
3、in 换 exists,not in 不要用,完全不走索引
4、is null 和 is not null都不走索引,索引里面不保存null的
5、<>这种也不走索引,可以拆分成< 和 >
6、join时,连接越少,性能越高。左连接,以左边的表结果为主;右连接,反过来;连接字段要求带索引
当数据库量达到上亿之后,索引用处就不大了,SQLserver数据库,两千万就可以了。当数据量过大,就应该从数据库设计层次找问题了。