index seek与index scan

低效
Index Scan(索引扫描):就全扫描索引(包括根页,中间页和叶级页): 

高效

Index Seek(索引查找):通过索引向前和向后搜索 :

 

 解释解释index seek和index scan
索引是一颗B树,
index seek是查找从B树的根节点开始,一级一级找到目标行。
index scan则是从左到右,把整个B树遍历一遍。
假设唯一的目标行位于索引树最右的叶节点上(假设是非聚集索引,树深度2,叶节点占用k页物理存储)。
index seek引起的IO是4,而index scan引起的IO是K,性能差别巨大。

seek:从B树根到叶节点的过程
扫描:当SEEK完成后,在叶节点执行范围或全部扫描(按查询的选择性会有不同

关于索引,可以仔细读读联机文档关于物理数据库体系结构部分
     查询条件中不要包含运算

这些运算包括字符串连接(如:select * from Users where UserName + ‘pig’ = ‘张三pig’),通配符在前面的Like运算(如:select * from tb1 where col4 like ‘�’),使用其他用户自定义函数、系统内置函数、标量函数等等(如:select * from UserLog where datepart(dd, LogTime) = 3)。

         SQLServer在处理以上语句时,一样没办法估算开销。最终结果当然是clustered index scan或者tablescan了。


    查询条件中不要包含同一张表内不同列之间的运算

所谓的“运算”包括加减乘除或通过一些function(如:select * from tb where col1 – col2 = 1997),也包括比较运算(如:select * from tb where col1 > col2)。这种情况下,SQLServer一样没办法估算开销。不论col1、col2上都有索引还是创建了col1、col2上的覆盖索引还是创建了col1 include col2的索引

但是这种查询有解决办法,可以在表上多创建一个计算字段,其值设置为你的“运算”结果,再在该字段上创建一个索引,就Ok了。

(结果集/总行数)被称为选择性,比值越大,选择性就越高。

你得到了它,本文的重点就是选择性。

统计信息,说白了,就是表中某个字段取某个值时有多少行结果集。统计信息可以说是一种选择性的度量,SQLServer就是根据它来估算不同查询计划的优劣。

若表中总行数为1w,采样行数为1w。provider_no值为21的只有1行,而值为500的行则有4824行。

 

我们知道,SQLServer会缓存查询计划,假如有这么一个存储过程:

create proc myproc

(

    @pno int

)

as

select * from charge where provider_no = @pno

第一次我们传进来一个21,OK,它会缓存该存储过程的执行计划为nonclustered index seek那个。后来我们又传进来一个500,完蛋了,服务器发现它有一个myproc的缓存,so,又通过nonclustered index seek执行,接着你的同伙看到你的查询花费了巨量的IO,于是,你被鄙视了。

这说明了啥?说明如果你的查询选择性变动剧烈,你应该告诉SQLServer不要缓存查询计划,每次都应该重新评估、编译。实现方法很简单,查询的尾巴上加一个option(recompile)好了。而且SQL2k5还有一个nb的 feature,可以每次只重新编译存储过程的一部分(当然,你也可以选择重新编译整个存储过程,这取决于你的需求。详见联机文档。)

 

原文链接:http://blog.csdn.net/pumaadamsjack/article/details/6597357

转载于:https://www.cnblogs.com/sunzhenyong/p/4739573.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sys.dm_db_index_operational_stats是一个系统视图,用于提供有关数据库索引操作的性能计数器信息。它提供了有关单个索引的更详细的统计信息,包括读取、写入和锁定等操作的数量和持续时间。下面是使用sys.dm_db_index_operational_stats的示例: 1. 获取所有索引的统计信息: ``` SELECT * FROM sys.dm_db_index_operational_stats(NULL, NULL, NULL, NULL) ``` 2. 获取特定表的索引统计信息: ``` SELECT * FROM sys.dm_db_index_operational_stats(DB_ID(), OBJECT_ID('TableName'), NULL, NULL) ``` 3. 获取特定索引的统计信息: ``` SELECT * FROM sys.dm_db_index_operational_stats(DB_ID(), OBJECT_ID('TableName'), INDEXPROPERTY(OBJECT_ID('TableName'), 'IndexName', 'IndexID'), NULL) ``` 4. 获取特定索引的读取、写入和锁定统计信息: ``` SELECT index_id, user_seeks, user_scans, user_lookups, user_updates, last_user_seek, last_user_scan, last_user_lookup, last_user_update, system_seeks, system_scans, system_lookups, system_updates, last_system_seek, last_system_scan, last_system_lookup, last_system_update, row_lock_count, row_lock_wait_in_ms, page_lock_count, page_lock_wait_in_ms FROM sys.dm_db_index_operational_stats(DB_ID(), OBJECT_ID('TableName'), INDEXPROPERTY(OBJECT_ID('TableName'), 'IndexName', 'IndexID'), NULL) ``` 注意,sys.dm_db_index_operational_stats提供的统计信息可能会随着时间的推移而发生变化,因此建议在不同时间点上收集和比较统计信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值