tsql - SQL Server:优化器智能,在 UNION ALL 查询中的同一个表上有多个索引
问题描述
我正在尝试为一个相当大的表编写查询(1000 万以上是典型的大小),其结果需要根据某些业务逻辑在各种谓词/条件上进行过滤。我的问题:查询优化器(在 SQL Server 2008+ 中)是否尝试对整个查询使用单个索引,还是尝试在逐个查询的基础上使用不同的索引?
考虑以下:
--Use Index A
SELECT Set1
FROM ATable
WHERE AColumn = sarg-able value
UNION ALL
--Are we stuck with Index A?
SELECT Set2
FROM ATable
WHERE BColumn = sarg-able value
如果我们为 Set1 选择索引 A,我们是否会在整个查询中使用索引 A,或者优化器是否足够聪明,可以为 Set2使用不同的索引(假设存在一个索引)?
解决方案
@andreyNikolov 所说的一切都是 100% 正确的。这是您可以通过查看实际执行计划(未估计执行计划)轻松自行解决的问题。请注意以下示例数据、表和索引结构:
USE tempdb -- safe place in Dev to test this kind of thing...
GO
-- sample data and indexes
IF OBJECT_ID('dbo.ATable','U') IS NOT NULL DROP TABLE dbo.ATable
CREATE TABLE dbo.ATable
(
Set1 INT NOT NULL,
Set2 INT NOT NULL,
AColumn INT NOT NULL,
BColumn INT NOT NULL
);
INSERT dbo.ATable (Set1, Set2, AColumn, BColumn)
VALUES (1,2,3,3),(1,2,4,4),(5,5,6,6),(11,22,40,40),(11,20,40,44),(11,22,14,4),(1,2,3,3);
CREATE NONCLUSTERED INDEX indexA ON dbo.ATable(AColumn) INCLUDE(Set1);
CREATE NONCLUSTERED INDEX indexB ON dbo.ATable(BColumn) INCLUDE(Set2);
现在在“包括实际执行计划”打开的情况下运行以下命令。
SELECT Set1 --Use Index A
FROM dbo.ATable
WHERE AColumn = 3
UNION ALL
SELECT Set2 --Use Index B
FROM dbo.ATable
WHERE BColumn = 4;
...以及执行计划:
UNION ALL 上面的查询对 IndexA 的键列 (AColumn)执行非聚集查找。因为我将 Set1 作为 IndexA 上的包含列包含在内,所以 IndexA 可以满足查询而无需针对 Rid 或 Key 查找。这就是索引的设计方式。UNION ALL 下面的查询也是如此,只是它使用的是 IndexB。
同样,一旦您完全了解如何阅读执行计划,您自己就很容易弄清楚这一点。
推荐阅读
- android - 对话框不显示其内容
- c# - EntityException - 底层提供程序在打开时失败
- javascript - 在搜索组件 React、Semantic-UI-React 中渲染搜索结果的问题
- javascript - 如何在浏览器(react 或 vanilla js)中实现滚动劫持(scrolljacking)?
- c - 试图将数组中的数据保存到文件中
- android - 如何使用 Dagger2 提供 GoogleSignInOptions?
- excel - 为什么我突然收到“编译错误:需要常量表达式”?
- java - 如何使用 Jackson 以不区分大小写的方式从 Json 对象反序列化为 Boolean.class?
- unity3d - 在 Unity 中,我怎样才能得到一个 2d 多边形对撞机,它是一个大对撞机的面积减去大对撞机内的一些较小的对撞机?
- recaptcha-v3 - Google Reaptcha v3 仍然让垃圾邮件通过