再强调一遍,SQLServer获取数据,总是以页为单位,就算是只读取一行也会获取整张页(见《写有效率的SQL查询(I)》)现在有一条简单查询(如:select * from tb where col2 = 99,col2是tb表中的非聚集索引),假设会返回100行。 Ok,我们来分析如果以Index seek来查找这100行会有多少IO。index seek每次都从索引树根节点开始查找,找到中间级节点(99对应的索引行),然后从该节点行开始连续遍历所有col2为99的索引行。在遍历这些行时,每拿到一条,都会通过该条索引行中聚集索引键值去聚集索引树中index seek,然后从数据页中获取数据。在最坏的情况下,col2为99对应的索引行跨越了全部4个叶级非聚集索引页(当然,这没啥可能性,举例而已,切勿深究);每次通过聚集索引树进行index seek,IO开销最坏情况下是一个根节点,一个中间级节点,一个数据页,一共要seek100次,开销300个逻辑IO。综上,通过nonclustered index seek总共开销是305个IO。 要知道,我们的基础表数据页一共才250页,这说明了啥?说明就算是我从头到尾扫描一遍表也比noncustered index seek快。这时,SQL2k5会产生一个完完全全的clustered index scan执行计划来搞定表扫描。好了,现在我们再来分析select * from tb1 where col2 = 1。假设它的结果集为5行。如果这时还是进行nonclustered index seek的话,逻辑IO按照上面相似的分析,应该是19个IO,远远要小于整个的clustered index scan。这时,SQLServer自然会采用nonclustered index seek。
a=1 的记录数占表总记录数的绝大多数的时候, 不会使用 a 上的索引 如果你的表中没有聚集索引, 基本上 select * ... where 的查询也不会走 where 列上的索引
每次通过聚集索引树进行index seek,IO开销最坏情况下是一个根节点,一个中间级节点,一个数据页,一共要seek100次,开销300个逻辑IO。综上,通过nonclustered index seek总共开销是305个IO。 要知道,我们的基础表数据页一共才250页,这说明了啥?说明就算是我从头到尾扫描一遍表也比noncustered index seek快。这时,SQL2k5会产生一个完完全全的clustered index scan执行计划来搞定表扫描。 看这个呀.
Ok,我们来分析如果以Index seek来查找这100行会有多少IO。index seek每次都从索引树根节点开始查找,找到中间级节点(99对应的索引行),然后从该节点行开始连续遍历所有col2为99的索引行。在遍历这些行时,每拿到一条,都会通过该条索引行中聚集索引键值去聚集索引树中index seek,然后从数据页中获取数据。在最坏的情况下,col2为99对应的索引行跨越了全部4个叶级非聚集索引页(当然,这没啥可能性,举例而已,切勿深究);每次通过聚集索引树进行index seek,IO开销最坏情况下是一个根节点,一个中间级节点,一个数据页,一共要seek100次,开销300个逻辑IO。综上,通过nonclustered index seek总共开销是305个IO。
要知道,我们的基础表数据页一共才250页,这说明了啥?说明就算是我从头到尾扫描一遍表也比noncustered index seek快。这时,SQL2k5会产生一个完完全全的clustered index scan执行计划来搞定表扫描。好了,现在我们再来分析select * from tb1 where col2 = 1。假设它的结果集为5行。如果这时还是进行nonclustered index seek的话,逻辑IO按照上面相似的分析,应该是19个IO,远远要小于整个的clustered index scan。这时,SQLServer自然会采用nonclustered index seek。
如果你的表中没有聚集索引, 基本上 select * ... where 的查询也不会走 where 列上的索引
要知道,我们的基础表数据页一共才250页,这说明了啥?说明就算是我从头到尾扫描一遍表也比noncustered index seek快。这时,SQL2k5会产生一个完完全全的clustered index scan执行计划来搞定表扫描。 看这个呀.
你没有数据,就敢说有多少页------------------------------------------一行记录8060字节, 这是上限, 一页 8 K, 差不多一页最少是 10 条记录
楼主说才 9 条记录, 你说理论的页数是不是 1 页呢?
当然, 如果数据经过大的变动, 导致数据存储不连续, 这种情况会超过1页的, 但我说的也是估计值
9条,如果某列是char(7000)呢?
你一共有9条记录,满足条件的有3条。
你的sql是select *
如果要用你的非聚集索引,那么sql server要从非聚集索引的根开始查找-->到非聚集索引中间级索引页-->非聚集索引索引叶子层
然后根据索引叶子层的聚集索引键-->到聚集索引根-->到聚集索引中间级索引页-->数据页而如果直接用聚集索引查找,那么就是聚集索引根-->到聚集索引中间级索引页-->数据页.关键是看哪个成本高了。如果你是10W记录,满足的只有3条,就肯定用你的非聚集索引了。
一行就可能存在7000字节的列,那么一个数据页最8192字节,还要有96字节的头,还有要偏移字节,留给数据页的不足 8096字节吧?
如果一行存在7000字节的列,那么9行就应该有9个数据页吧。一般情况下,还有一个iam页,一个非聚集索引(根+中间级+索引叶子)页
噢,老大 ^^
我是看着老大的书一路走过来的,记得06年我坐公交车天天都带着那本sql server开发与管理,一有空就看。