【问题标题】:SQL Server 2008 seems to be picking the PK Index for every query, even if a better one seems to existSQL Server 2008 似乎为每个查询选择了 PK 索引,即使似乎存在更好的索引
【发布时间】:2011-07-08 21:46:05
【问题描述】:

听起来和what's asked here的情况类似,但我不确定他的详细信息是否与我的相同。

基本上我有一个关系表,我们称之为用户:

User
-----------
int Id
varchar<100> Name
int AddressId
varchar<max> Description

它具有以下索引: PK_User_Id - 显然是主键。 IX_User_AddressId - 仅包括 AddressId。

当我运行以下查询时:

select Id, Name, AddressId, Description from User where AddressId > 200

执行计划显示扫描已完成,并且使用了 PK_User_Id。

如果我运行这个查询:

select AddressId from User where AddressId > 200

执行计划显示已完成扫描并使用了 IX_User_AddressId。

如果我在 IX_User_AddressId 索引中包含所有列,那么我的原始查询将使用正确的索引,但我必须这样做似乎仍然是错误的。

所以我的 SQL 菜鸟问题是这样的:我必须做些什么才能让我的查询使用最快的索引?要非常具体,因为我无法弄清楚这一点,所以我一定是智障。

【问题讨论】:

  • 表格中有多少行与每个示例中返回了多少行
  • 如果您使用 = 运算符而不是 > 运行相同的查询,是否使用了非聚集索引?正如 Andrew 所暗示的,我们需要知道 AddressId>200 的行的比例,以确定 MSSQL 是否适当地使用了索引统计信息。

标签: sql tsql indexing sql-execution-plan


【解决方案1】:

您的查询看起来像是已倾斜,因为您的索引未涵盖您想要的所有字段,我会说它已倾斜(请查看 Kimberly Tripp - Tipping Point)并使用了主键索引,我会猜得很好作为您的聚集索引。

【讨论】:

  • 您说得对,先生,经过一些实验,SQL Server 似乎比我更聪明。作为一名程序员,我习惯于让计算机做我告诉他们做的事,因为我更聪明(!!!),但是 SQL 与软件开发并不完全相同,因为我在搞乱由比我聪明得多的人开发的软件。故事的寓意是,如果 SQL 没有使用您创建的索引,那是因为它知道得更好(通常)。
  • 已编辑:添加了 Kimberly 帖子的链接,因为它对我有很大帮助。 (并固定了她的名字);)
【解决方案2】:

当您的 IX_User_AddressId 索引仅包含 AddressId 时,SQL 必须在基表上执行书签查找以检索您的其他列(IdNameDescription)。如果表足够小,SQL 可能会认为扫描整个表比使用备用索引和书签查找更有效。当您将这些其他列添加到索引中时,您会创建所谓的覆盖索引,这意味着满足您的查询所需的所有列都在索引本身中可用。这是一件好事,因为它将消除书签查找。

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多