一些简单的测试结论
在本机经过一些简单的测试,记录数6W条,得出以下结论,不同的硬件环境和数据记录数,可能会有不一样的结论
1.in, or, exists, like, not in , not exists都会利用索引,SQLSERVER会做性能优化,查询性能都差不多
2.in , exists, not in , not exists如果作子查询,如果有索引的话会利用索引分别查出相应的记录到内存,然后做join匹配运算
3.union, union all性能不是很好,重复查询,有时不如in,or
4.order by 一般情况比较损耗cpu,如果没有什么限定条件并且order by字段又有索引,则会利用此索引排序,此时就不损耗cpu而是IO
5.<>等负向查询虽会利用索引,但IO性能依然很差,因为SQLSERVER是按BTree二分查找法得到相应的记录
6.对字段做函数查询性能很差,如charindex(‘x‘, 字段) > 1,不会利用索引,性能较差,而且要对字段进行运算。
7.对表进行查询,如果where条件是用and连接起来,
比如:where addtime >= ‘2013-12-28‘ and addtime < ‘2013-12-29‘ and note like ‘%abcd%‘ and ....and ....,
SQLSERVER会选择最优的查询条件查询,上面语句,假如addtime做了索引,则SQLSERVER会用addtime索引查询,抽取相关页到内存中,
然后like等将在内存中匹配,对于IO的影响应该是没有的。
8.每个表都应该设置聚集索引,最好选择惟一的,最小的列,聚集索引列可以与主键不同,聚集索引目的是提升查询性能,而主键则代惟一一条记录,
大多数情况下是可以一样的,比如:订单ID(int),订单编号 char(16),则建议订单ID作为聚集索引,订单编号做惟一索引,从业务上讲订单编号应为主键,
从系统角度也可以把订单ID定义为主键。
如果聚集索引是惟一的话可以直接定位到哪条数据,非聚集索引的子页都聚集索引页,所以聚集索引的好坏将影响到所有的索引。
非聚集索引注意的问题
如果非聚集索引的重复记录很多,即使使用此条件做查询,也不会用相应的非聚集索引,此时SQLSERVER会采用全表扫描,
因为非聚集索引会重复抽取符合条件的页到内存中,导致逻辑读取次数明显增加,对IO影响较大。比如:type作非聚集索引,
在非聚集索引页中如果有10条记录在同一数据页中,会加重复载10次相同的数据页到内存中,至于SQLSERVER为什么会这样
处理,还不清楚。所以重复记录很多的字段不需要建索引。
非聚集索引中的覆盖索引
覆盖索引的意思是查询语句所有出现的字段都包含在索引中,这样SQLSERVER只要扫描索引页就可以得到所有需要的数据,覆盖索引
会明显提升性能。覆盖索引的语法:
create index indexname on tablename(索引字段1, 索引字段2,...) include(读取的字段1, 读取的字段2,...)
覆盖索引要注意的问题是1:不允许超出16个字段,2:数据越小越好。
总结:
以上只是个人的一些浅薄的结论,欢迎指正,SQL语句优化,还是要在生产环境调校为准