SELECT COUNT(A) FROM PlateReForum WHERE B=10213 AND C=0 AND D=0
A 有非聚集索引
B 有非聚集索引
E 有聚集索引
C,D列没建索引
把AND后面的去掉,执行消耗非常小,READS为50.加上AND,则消耗非常大,READS为10000
用执行计划,显示 键查找;开销:100%。谓词 C,D。对象 E_INDEX
我把C,D列建个复合非聚集索引,但是结果却没有变。如上面显示的那样。我建了索引,为什么没有用我建的那个索引,而还是用E_INDEX呢?有人知道问题所在吗?这个表有1000W行.
 
问题补充:执行计划 建议创建 B,C,D 非聚集复合索引,B已经有索引的,这样合适吗?

解决方案 »

  1.   

    E_INDEX是聚集索引,查询会优先使用
    可以创建 B,C,D 非聚集复合索引
      

  2.   

    select * from tb with (INDEX (...)) 试试
      

  3.   

    SQL 不会用 C,D列建个复合非聚集索引,因为where 的第一个条件是B建议B,C,D 一起建非聚集索引,那么它满足第一个条件B, SQL 就会使用此索引或者B, C , D非聚集索引+Include(A) 形成覆盖索引 
      

  4.   

    我建了B,C,D非聚集复合索引,那么以前的B索引可以删除掉吗
      

  5.   


    如果你只想用于:
    SELECT COUNT(A) FROM PlateReForum WHERE B=10213 AND C=0 AND D=0
    查询,那么可以删除B索引,如果你还有其他查询有涉及到B 的
    例如:
    SELECT XX FROM XXX WHERE B=10213
    ,可能不用删除
      

  6.   


    创建 B,C,D非聚集复合索引后,是可以删除以前 B 上索引的。因为对于复合索引,如果语句中的 WHERE 子句中引用的列是复合索引码前部分的列(如,WHERE B=...,WHERE C=... AND B=...),查询是可以使用这个复合索引加速查询的。
      

  7.   

    单独的 SELECT COUNT(A) FROM PlateReForum WHERE B=10213 查询完全可以利用 B 上的非聚集索引执行 INDEX SCAN 操作,这是因为 COUNT(A) 只对满足 B=10213 条件的行进行计数。而 SELECT COUNT(A) FROM PlateReForum WHERE B=10213 AND C=0 AND D=0 语句只能使用表的聚集索引进行 INDEX SCAN 操作,因为缺少 B,C,D 非聚集复合索引。由于  B 上的非聚集索引所占用的叶级索引页远远小于表的聚集索引占用的索引页,因此读取这些页面所需的 I/O 会远远小于读取聚集索引的叶级索引页。
      

  8.   

    应该是 ,
    SELECT COUNT(A) FROM PlateReForum  会使用 A 上的非聚集索引进行 INDEX SCAN 操作,
    SELECT COUNT(*) FROM PlateReForum WHERE B=10213 会使用 B 上的非聚集索引进行 INDEX SEEK 操作,
    SELECT COUNT(A) FROM PlateReForum WHERE B=10213 会使用表的聚集索引进行 CLUSTERED INDEX SCAN 操作。