SQL Server为什么索引不与OR一起使用

vic*_*tor 5 sql sql-server indexing

我一直在研究索引并试图了解它们的工作原理以及如何使用它们来提高性能,但我遗漏了一些东西.

我有下表:

:

| Id | Name | Email | Phone |
| 1  | John |  E1   |  P1   |
| 2  | Max  |  E2   |  P2   |
Run Code Online (Sandbox Code Playgroud)

我正在尝试找到索引列的最佳方法,EmailPhone考虑到(大多数情况下)查询将是表单的

[1] SELECT * FROM Person WHERE Email = '...' OR Phone = '...'
[2] SELECT * FROM Person WHERE Email = ...
[3] SELECT * FROM Person WHERE Phone = ...
Run Code Online (Sandbox Code Playgroud)

我认为最好的方法是使用两列创建单个索引:

CREATE NONCLUSTERED INDEX [IX_EmailPhone]
ON [dbo].[Person]([Email], [PhoneNumber]);
Run Code Online (Sandbox Code Playgroud)

但是,使用上面的索引,只有查询[2]受益于索引查找,其他查询[2]使用索引扫描.

我还尝试创建多个索引:一个包含两列,一个用于电子邮件,一个用于电子邮件.在这种情况下,[2]和[3]使用seek,但[1]继续使用scan.

为什么数据库不能使用带有或的索引?考虑到查询,该表的最佳索引方法是什么?

Gor*_*off 1

使用两个单独的索引,一个 on (email),一个 on (phone, email)

OR比较困难的。AND如果您的条件通过而不是连接OR,那么您的索引将用于第一个查询(但不是第三个查询,因为phone不是索引中的第一个键)。

您可以将查询编写为:

SELECT *
FROM Person 
WHERE Email = '...' 
UNION ALL
SELECT *
FROM Person 
WHERE Email <> '...' AND Phone = '...';
Run Code Online (Sandbox Code Playgroud)

SQL Server 应该为每个子查询使用适当的索引。