Sql 为什么即使我有非聚集索引也会有键查找?

Sql 为什么即使我有非聚集索引也会有键查找?,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我面临一个问题,即即使我已经在isunder和IsGrantee上创建了索引,在查询计划中也会显示键查找。请参阅随附的屏幕截图和输出列表 该表大约包含50万条记录 如果您的索引不是覆盖索引,将进行键查找。不覆盖意味着它不能提供查询所需的所有列。因此,要获得集群索引上的剩余列键,需要对其进行查找 You can try following Drop unnecessary columns from select list Include columns in your non clus

我面临一个问题,即即使我已经在
isunder
IsGrantee
上创建了索引,在查询计划中也会显示键查找。请参阅随附的屏幕截图和输出列表

该表大约包含50万条记录


如果您的索引不是覆盖索引,将进行键查找。不覆盖意味着它不能提供查询所需的所有列。因此,要获得集群索引上的剩余列键,需要对其进行查找

You can try following
  Drop unnecessary columns from select list
  Include columns in your non cluster index to make it covering.

此外,如果减少结果集中的行数,则进行一些键查找不会有太大影响。

哪些列可以
isunder
IsGrantee
实际索引?关于实际关系和索引结构的详细信息将非常有用。它们是包含关系的实际外键,还是仅包含布尔标志?如果只有布尔值,数据库可能不会认为它们非常“选择性”。你能发布你的查询吗?”托马斯W:你是对的。这只是布尔标志。你可以尝试用这两个标志和你用于连接的列(如果有连接)创建索引。@Szymon:我已经在这两个列上创建了索引(这是我的问题)。join列是DocumentNameID,它是聚集索引。我认为索引中只有布尔标志不是很有用——您有50万条记录,因此一个布尔值的索引仍有25万条记录需要扫描。效率很低。引擎更喜欢具有高选择性的索引,该索引覆盖查询计划所需的列。同意Thomas的观点。布尔列上的索引的一个用例是当true/false的数量非常少时。在这种情况下,可以尝试筛选索引。有时TOP也可以触发键查找。我有一个查询返回了20行,从0.1秒到超过100秒,因为我添加了前50行。这导致所有非聚集索引都转换为一个键查找,最终扫描整个表。顺便说一句,没有一个非聚集索引覆盖,但为什么它们要覆盖呢?SQL应该知道它是否正在扫描整个表,并不惜一切代价避免这样做。我相信这是优化器中的一个bug,因为我可以根据需要复制它。