create nonclustered index Example
On dbo.Orders(OrderID,CustomerID)
Include(StatusID)
将此索引读取为:从 Orders 表中创建 OrderID、CustomerID、StatusID 的系统维护副本。按 OrderID 订购此副本,并与 CustomerID 断绝关系。
select CustomerID from Orders where OrderID = 100
由于索引是按 OrderID 排序的,因此查找第一个符合条件的记录很快。一旦我们找到第一条记录,我们可以继续在索引中读取,直到找到 OrderID 不是 100 的记录。然后我们可以停止。由于我们想要的所有列都在索引中,我们不必查找实际的表。伟大的!
select OrderID from Orders where CustomerID = 20
由于索引按 OrderID 排序,然后按 CustomerID 排序,因此符合条件的记录可以出现在索引中的任何位置。第一条记录可能符合条件(OrderID = 1,CustomerID = 20)。最后一条记录可能符合条件(OrderID = 1000000000,CustomerID = 20)。我们必须阅读整个索引才能找到符合条件的记录。这是不好的。 一个小帮助:因为我们想要的所有列都在索引中,所以我们不必查找实际的表。因此,从技术上讲,第二个查询得到了索引的帮助——只是没有到其他查询得到帮助的程度。
select OrderID, StatusID from Orders where CustomerID = 100 and OrderID = 1000
由于索引是按 OrderID 然后按 CustomerID 排序的,因此查找第一个符合条件的记录很快。一旦我们找到第一条记录,我们就可以继续在索引中读取,直到找到一条不合格的记录。然后我们可以停下来。由于我们想要的所有列都在索引中,我们不必查找实际的表。伟大的!
复合索引是否改进了使用复合中的一项的查询?
有时!
或者是否也应该在这些列上创建单独的索引(即 OrderID、CustomerID)以满足查询 1 和 2?
有时不是!
真正的答案是索引声明中列的顺序决定了索引中记录的顺序这一事实的细微差别。一些排序有助于一些查询,而另一些则没有。您可能需要再补充一个索引以涵盖 CustomerID、OrderID 的情况。
“由于我们想要的所有列都在索引中,我们不必查找实际的表”——所以索引可以用于读取目的,尽管不用于查找/查找目的?
当索引(它是表的一部分的副本)包含解析查询所需的所有信息时,不需要读取实际的表。索引“覆盖”查询。