结构:
pk_FeiZaiId int 主键,pk_OrderHeadId int,pk_OrderColorId int,nc_SizeCode nchar,nc_CraftCode nchar,n_Qty int
聚焦索引:pk_FeiZaiId
组合索引:pk_OrderHeadId + pk_OrderColorId + nc_SizeCode + nc_CraftCode表记录:13101693 行第一查询语句(用时0秒):
select pk_FeiZaiId,pk_OrderHeadId,pk_OrderColorId,nc_SizeCode,nc_CraftCode from t_op_ProdOrderFZ where pk_OrderHeadId = 1608000879第二查询语句(用时38秒):
select pk_FeiZaiId,pk_OrderHeadId,pk_OrderColorId,nc_SizeCode,nc_CraftCode,n_Qty from t_op_ProdOrderFZ where pk_OrderHeadId = 1608000879
查看执行计划,第二查询语句没有用到组合索引,于是用下面查询语句
第三查询语句(用时6秒):
select pk_OrderHeadId,pk_OrderColorId,nc_SizeCode,nc_CraftCode,n_Qty from t_op_ProdOrderFZ with(index(IX_t_op_ProdOrderFZ)) where pk_OrderHeadId = 1608000879 三种查询语句都返回46460行,问题是我指定了组合索引为何还是要比不返回 n_Qty这列的语句要慢呢?第三种查询语句的执行计划种多了一项使用书签查找占有了全部时间,这是怎么回事啊?

解决方案 »

  1.   

    如果n_Qty这个列很大,比如二进制字段,也会很慢
      

  2.   

    因为得先使用和聚集索引相同的查找方法找到该索引的行指定位(行定位器),
    然后 由行定位器找数据,当没有n_Qty列时直接由索引表取出数据了,当有这一列时SQL server综合碎片等的 影响 一般采用两种方式来查询数据:
    1、选择条件良好,走索引
    2、选择条件不佳,放弃索引你这种情况估计:1、碎片(碎片对索引顺序扫描影响挺大)2、sql server估算嵌套迭代太大放弃索引
      

  3.   

    如果你想第二个也高速,这样建索引:
    sql 2000:
    create index ix_01 on t_op_ProdOrderFZ (pk_OrderHeadId,pk_OrderColorId,nc_SizeCode,nc_CraftCode,n_Qty)
    sql 2005:
    create index ix_01 on t_op_ProdOrderFZ (pk_OrderHeadId,pk_OrderColorId,nc_SizeCode,nc_CraftCode)include(n_Qty)
      

  4.   

    如果没有返回n_Qty列,则数据可以直接从组合索引的叶子层直接读到所有数据。
    如果有返回n_Qty列,则数据需要从通过组合索引的叶子层读到pk_OrderHeadId,pk_OrderColorId,nc_SizeCode,nc_CraftCode这些数据,然后再通过组合索引上的聚集索引键值再去聚集索引的叶子层返回n_Qty数据,多了一个步骤,就慢了。
      

  5.   

    楼上的兄弟,那就是说没有的优化罗?如果把n_Qty这列也加入索引,会不会快了呢?
      

  6.   

    多谢,我之前也想过是否加入n_Qty列后是否有改善,但不知道取数据列如果不在索引中也会有影响的。不知道增加这列到索引中后,对Insert、Update操作有多大影响,索引数据大小有多大改变呢?
      

  7.   

    影响应该不会很大。索引数据大小的改变跟n_Qty数据的重复值个数有关。
    注意组合索引所有列总长不能超过900字节。
      

  8.   

    新手理解:
    非聚集索引應該如此使用
    若查詢語句為SELECT A,B,C,D,E,F FROM TABLE WHERE A..... AND B..... AND C.....
    建一個非聚集索引,索引鍵為A,B,C(按WHERE中出現的順序),包含非鍵列D,E,F

    CREATE NONCLUSTERED INDEX **** ON TABLE (A,B,C) INCLUDE (D,E,F)
    索引最好覆蓋SELECT的所有字段,但不必將所有字段設為索引鍵,只需要將查找條件出現的字段作為索引鍵就可以,其余包含進去! 
      

  9.   

    Insert的速度非常大影响,原来没有把n_Qty这列加入索引时,插入300万行数据在30分钟,现在加入这列后插入100万行数据用了2个多小时,n_Qty这列数据98%都为24,如果n_Qty这列数据很多重复,加入索引后怎么对插入速度这么大影响啊?
      

  10.   

    表结构在一楼,就一个聚焦索引及一个组合索引,表六个字段中四个INT类型,两个NCHAR类型(长度为10),怎么算一行多少字节呢?
      

  11.   

    电脑是双核+1G内存,自己用的普通电脑,用到游标及While循环,没有加入n_Qty这列到索引中时插入5000万行数据用了5小时。今天加了n_Qty到索引中后插入100万行就用了2个多小时,这列加入后应该是有影响的。
      

  12.   

    1G内存。。
    游标+while。。能跑完程序算不错的了。可能到达一个瓶颈了,造成时间陡升。对这种大批量的插入操作,可以先drop索引,插完后再去重建。
    以后少量插入应该影响不会很大。
      

  13.   

    我现在又把n_Qty这列从索引中去掉,在原表基础上继续插入2000万行用了四个小时,比加入n_Qty这列到索引中快多了。
      

  14.   

    学习。查询时先不要n_qty列,然后增加n_qty,最后关联update会不会快些?
      

  15.   

    现在我想知道的问题就是加入n_Qty这列后,如果n_Qty这列98%都是重复数字对Insert操作到底有多大影响。因为这个表以后数据量相当大,所有建立表时应该要把所有问题考虑清楚才行啊。
      

  16.   

    光是n_Qty这列98%并不能知道你这个通过非聚索引访问数据分页的频繁程度