为什么我不能做以下的事情?我希望这个“常用”列上的过滤器既快又能够在不需要表扫描的情况下返回它。
CREATE NONCLUSTERED INDEX Ix_Foo
ON Foo (ForeignKeyID, ObjectID)
INCLUDE (ObjectID)
当我这样做时,我收到错误:
不能在索引中使用重复的列名。列名'ObjectID'不止一次列出。
我喜欢这样的查询,我想要返回ObjectID以及过滤它。这里的子查询是我的意思的一个例子:
SELECT something FROM Bar
WHERE Bar.FooID IN
(SELECT ObjectID FROM Foo WHERE ForeignKeyID=13 AND ObjectID IN (12, 13, 14, 15))
我在概念上缺少什么?
答案 0 :(得分:6)
原因是ObjectId
已作为关键列包含在索引中,并且您尝试将其作为非关键列包含在内,这是不必要的。
CREATE NONCLUSTERED INDEX Ix_Foo
ON Foo (ForeignKeyID, ObjectID)
这应该足以满足您的目的。
您通常需要包含非键列,以便(引用MSDN):
它们可以是不允许作为索引键列的数据类型。
在计算索引键列数或索引键大小时,数据库引擎不会考虑它们。
答案 1 :(得分:2)
从概念上讲,SQL Server中未过滤的非聚集索引中的叶级别在基础表中每行有1行数据。叶级别中的列是以下不同的列:
例如:
CREATE TABLE t1 (id int not null, first_name varchar(20), last_name varchar(20))
CREATE CLUSTERED INDEX CIX_t1 on t1 (id)
CREATE INDEX IX_t1_a on t1 (first_name)
CREATE INDEX IX_t1_b on t1 (first_name) INCLUDE (id)
CREATE INDEX IX_t1_c on t1 (first_name) INCLUDE (id, last_name)
CREATE INDEX IX_t1_d on t1 (first_name, last_name)
CREATE INDEX IX_t1_e on t1 (first_name, id)
IX_t1_a的叶级由(first_name,id)
组成IX_t1_b的叶级由(first_name,id)
组成IX_t1_c的叶级别由(first_name,id,last_name)
组成IX_t1_d的叶级别由(first_name,id,last_name)
组成IX_t1_e的叶级由(first_name,id)
组成列永远不会包含两次。在上面的示例中,索引a,b,c是彼此重复的。同样,索引c和d也是重复的。 (根据聚簇索引和非聚簇索引的唯一性,非叶级别存在细微差别,但索引可用于哪些查询,它们是相同的。)