【问题标题】:Why does SQL Server sometimes choose an index scan over a bookmark lookup?为什么 SQL Server 有时会选择索引扫描而不是书签查找?
【发布时间】:2012-01-18 03:09:56
【问题描述】:

我们有一个简单的表格,如下所示:

OrderID primary key / clustered index
CustomerID foreign key / single-column non-clustered index
[a bunch more columns]

然后,我们有一个这样的查询:

SELECT [a bunch of columns]
FROM Orders
WHERE CustomerID = 1234

我们发现有时 SQL Server 2008 R2 会在非聚集索引上进行查找,然后在聚集索引上进行书签查找(我们喜欢这样 - 它非常快)。

但在其他看似随机的情况下,SQL Server 反而对聚集索引进行扫描(非常慢 - 让我们的应用陷入爬行状态 - 而且它似乎在我们一天中最繁忙的时间执行此操作)。

我知道我们可以 (a) 使用索引提示,或者 (b) 增强我们的非聚集索引,以便它覆盖我们选择的大量列。但是 (a) 将逻辑与物理联系起来,关于 (b),我读到索引不应涵盖太多列。

我首先很想听听为什么 SQL Server 正在做它正在做的事情的任何想法。此外,任何建议将不胜感激。谢谢!

【问题讨论】:

  • 这些随机场合是否也使用单个CustomerID 进行查询,还是一次查询多行?书签查找是一项非常昂贵的操作,因此扫描速度更快的临界点非常低 - 远低于大多数人的预期
  • 谢谢大家。您帮助我意识到我们的问题可能是许多订单可以为单个客户返回 - 使查询非选择性。
  • 所以我想我们将创建一个覆盖索引 - 覆盖返回的 12 个左右的字段。然而(对我来说)这样做的一个缺点是我们可能会在查询中添加一个字段,而忘记扩展覆盖索引。我想我们需要用勿忘我来评论我们的查询。 :)

标签: sql-server sql-server-2008-r2


【解决方案1】:

您应该将索引设为covered index,这样就不需要进行书签查找。这是可能导致查询优化器忽略您的索引的潜在昂贵操作。

如果您使用的是 SQL Server 2005 或更高版本,则可以将它们添加为 included columns,否则您必须将它们添加为附加键列。

覆盖索引的性能始终优于非覆盖索引,尤其是对于非选择性查询。

【讨论】:

  • +1 好的推荐 - 如果可以创建一个可以被索引覆盖的查询
【解决方案2】:

CustomerID 的选择性将在查询优化器的决策中发挥一定作用。一方面,如果它是唯一的,那么相等操作将最多产生一个结果,因此几乎可以保证 SEEK/LOOKUP 操作。另一方面,如果可能有成百上千条记录与 CustomerID 的值匹配,那么聚簇索引扫描可能看起来更有吸引力。

您会惊讶于过滤器必须有多么选择性才能排除扫描。我找不到我最初从中提取此图的文章,但如果 CustomerID 1234 将匹配表中低至 4% 的记录,则对聚集索引的扫描可能更有效,或者至少看起来像这样优化器(它不能 100% 正确)。

CustomerID 上的非聚集索引上保存的统计信息导致优化器根据选择性标准在查找/扫描之间切换,这听起来至少是合理的。

您可以通过引入 JOIN 或 EXISTS 操作来诱使优化器使用索引:

-- Be aware: this approach is untested
select o.*
  from Orders o
       inner join Customers c on o.CustomerID = c.CustomerID
 where c.CustomerID = 1234;

或者:

-- Be aware: this approach is untested
select o.*
  from Orders o
 where exists (select 1
                 from Customers c
                where c.CustomerID = 1234 and
                      o.CustomerID = c.CustomerID);

另外请注意,使用这种 EXISTS 方法,如果您在 两个 表中的“连接”谓词(在本例中为 CustomerID 字段)上没有索引,那么您将最终得到一个嵌套循环,痛苦很慢。使用内部连接似乎更安全,但 EXISTS 方法有时会在它可以利用索引时占有一席之地。

这些只是建议;我不能说它们是否有效。只是想尝试一下,或者让常驻专家确认或否认。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 2011-09-25
    相关资源
    最近更新 更多