sql - 为什么要执行表扫描?

标签 sql sql-server indexing

SELECT X.ID, X.Field4
FROM 
        #TaxInvoiceData T
INNER JOIN
        xxx X
        ON  T.Id = X.Id
        AND Field2 = @VAR     
        AND Field3 = 'S'

当我在表 X 上运行查询时,进行全表扫描。我不明白为什么,因为表 X 的主键是

ID INT ASC
Field3 CHAR(2) ASC
Field2 DATETIME ASC  Unique Non-clustered

还有一个索引

Field2 DATETIME ASC  Non-Unique Non-clustered

只做事

SELECT ID
FROM xxx
WHERE 
    Field2 = @VAR   
AND Field3 = 'S'

是否进行索引查找

提前致谢。

最佳答案

简短的回答:因为优化器认为它会更快。

但是,让我们尝试了解优化器的想法。

由于您没有提供完整的表架构,我将假设 xxx.ID 上有一个聚集索引,并且 #TaxInvoiceData 是一个堆。您期望有一个计划,其中对 #TaxInvoiceData 中的每一行探测 PK 索引,但您选择了 xxx.Field4,这将需要书签查找每场比赛。这可能会导致 29,000 个随机 I/O 请求。哎哟。

相反,SQL Server 可以(而且显然将会)执行大量更高效的顺序 I/O 来进行表扫描,并且可能会针对 #TaxInvoiceData 进行快速哈希匹配。

那么你能做什么呢?您可以创建一个包含 Field4 的覆盖索引。或者您可以使用索引和连接提示来强制执行您正在寻找的计划(但我怀疑性能不会像您希望的那么好)。该查询的使用是否足够频繁,以至于给您的应用程序带来性能问题,或者您只是希望原则上消除表扫描?如果是后者,您可能会发现摆脱扫描的开销最终不值得。

<小时/>

编辑:

既然您提到表上没有聚集索引,这也可能会影响索引查找的效率。除非此表的插入事件非常频繁,否则请考虑将 PK 更改为集群。仅此一点就可能会改变计划,即使不会改变,也可能会由于开销的减少而加快其他操作的速度。

关于sql - 为什么要执行表扫描?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8313678/

相关文章:

mysql - 如何在 MySQL 中合并同一个表?

sql - 如何在 hive 中创建一个空的结构数组?

sql-server - 从表中选择全部将一列设置为带有 AS 的别名

arrays - 从 Google 表格中的数组中提取特定字段

Mongodb:在两个字段的数组上创建索引

mysql - 在一个查询的每一行中增加一个唯一列

java - 如何在基于spring的应用程序中开发查询设计器

mysql - 当不需要 int 时,创建 SQL 函数时出错(无法转换为 int)

sql - 数据流任务中的 SSIS 变量使用不正确

java - java中两种不同类型的索引数组