select * from t where a=1
表数据几十行,测试阶段!
我在a字段上建立了非聚集索引,a是外键!
我在查询分析器执行的时候,查看执行计划!没有用到我建的那个非聚集索引!为何?

解决方案 »

  1.   

    再强调一遍,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。
      

  2.   

    a=1 的记录数占表总记录数的绝大多数的时候, 不会使用 a 上的索引
    如果你的表中没有聚集索引, 基本上 select * ... where 的查询也不会走 where 列上的索引
      

  3.   

    每次通过聚集索引树进行index seek,IO开销最坏情况下是一个根节点,一个中间级节点,一个数据页,一共要seek100次,开销300个逻辑IO。综上,通过nonclustered index seek总共开销是305个IO。 
    要知道,我们的基础表数据页一共才250页,这说明了啥?说明就算是我从头到尾扫描一遍表也比noncustered index seek快。这时,SQL2k5会产生一个完完全全的clustered index scan执行计划来搞定表扫描。 
    看这个呀.
      

  4.   

    你select a from t where a=1就走你的索引了。
      

  5.   

    to: perfectaction 
    你没有数据,就敢说有多少页------------------------------------------一行记录8060字节, 这是上限, 一页 8 K, 差不多一页最少是 10 条记录
    楼主说才 9 条记录, 你说理论的页数是不是 1 页呢?
    当然, 如果数据经过大的变动, 导致数据存储不连续, 这种情况会超过1页的, 但我说的也是估计值
      

  6.   


    9条,如果某列是char(7000)呢?
      

  7.   

    其实这个问题应该是这样:
    你一共有9条记录,满足条件的有3条。
    你的sql是select *
    如果要用你的非聚集索引,那么sql server要从非聚集索引的根开始查找-->到非聚集索引中间级索引页-->非聚集索引索引叶子层
    然后根据索引叶子层的聚集索引键-->到聚集索引根-->到聚集索引中间级索引页-->数据页而如果直接用聚集索引查找,那么就是聚集索引根-->到聚集索引中间级索引页-->数据页.关键是看哪个成本高了。如果你是10W记录,满足的只有3条,就肯定用你的非聚集索引了。
      

  8.   

    同意,如果该表只有a这列,select * from t where a = 1也会走索引.
      

  9.   


    一行就可能存在7000字节的列,那么一个数据页最8192字节,还要有96字节的头,还有要偏移字节,留给数据页的不足 8096字节吧?
    如果一行存在7000字节的列,那么9行就应该有9个数据页吧。一般情况下,还有一个iam页,一个非聚集索引(根+中间级+索引叶子)页
      

  10.   


    噢,老大 ^^ 
    我是看着老大的书一路走过来的,记得06年我坐公交车天天都带着那本sql server开发与管理,一有空就看。
      

  11.   

    Garnett_KG 这厮够坏滴! 囧