索引和执行计划

时间:2016-03-30 10:06:57

标签: sql-server sql-server-2008 sql-server-2012

我知道聚集索引确定了表中数据的物理顺序。所以我创建了2个临时表来检查记录的物理顺序。

CREATE TABLE #My_table_1
  (
     ID   INT,
     COL1 INT,
     COL2 VARCHAR(20) UNIQUE,
     COL3 VARCHAR(20)
  );

CREATE CLUSTERED INDEX IX_Employee
  ON #My_table_1 (ID, COL1 DESC)

INSERT INTO #My_table_1 VALUES (1,10,'10','10');
INSERT INTO #My_table_1 VALUES (2,520,'20','10');
INSERT INTO #My_table_1 VALUES (3,50,'30','10');
INSERT INTO #My_table_1 VALUES (5,55,'65','10');    
INSERT INTO #My_table_1 VALUES (1,5,'100','10');            
INSERT INTO #My_table_1 VALUES (3,300,'50','10');
INSERT INTO #My_table_1 VALUES (3,40,'5','10');
INSERT INTO #My_table_1 VALUES (1,15,'4','10');
INSERT INTO #My_table_1 VALUES (5,100,'56','10');

CREATE TABLE #My_table_2
  (
     ID   INT,
     COL1 INT,
     COL2 VARCHAR(20) UNIQUE,
  ) 

CREATE CLUSTERED INDEX IX_Employee
  ON #My_table_2 (ID, COL1 DESC) --Creating a CLUSTERED INDEX on columns ID,COL1

INSERT INTO #My_table_2 VALUES (1,10,'10');
INSERT INTO #My_table_2 VALUES (2,520,'20');
INSERT INTO #My_table_2 VALUES (3,50,'30');
INSERT INTO #My_table_2 VALUES (5,55,'65'); 
INSERT INTO #My_table_2 VALUES (1,5,'100');         
INSERT INTO #My_table_2 VALUES (3,300,'50');
INSERT INTO #My_table_2 VALUES (3,40,'5');
INSERT INTO #My_table_2 VALUES (1,15,'4');
INSERT INTO #My_table_2 VALUES (5,100,'56');

当我查询这两个表时,我发现两个表中的记录顺序不同。为什么会这样? Selection_Order 所以我检查了执行计划,因为查询执行计划是不同的。 Execution Plan 任何人都可以解释,为什么会发生这种情况?我对Clustered index的理解是否错误?

1 个答案:

答案 0 :(得分:2)

我相信你对聚集指数的理解是正确的。您对此处的SQL Server优化程序,统计信息和排序有所了解。

如果查询优化器确定它有更好的方法,它可以随意忽略任何索引(甚至是提示的索引)。这种更好的方法是使用各种信息确定的 - 整本书都涉及 - 关于数据的选择性,数据类型,表的大小,列数等。即使对于聚簇索引,只有指定的数据保存在索引中;仍然必须为剩余的数据列进行查找。查看这些单独的数据列与仅进行表扫描的成本是什么?

最后,不保证不会以任何顺序返回该数据。当使用聚集索引时,它可能巧合地与物理顺序匹配,但这不是故意的。这是副作用。以已知有序方式返回数据的唯一方法是使用ORDER BY。