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

标签 sql sql-server indexing

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

我有下表:

:

| Id | Name | Email | Phone |
| 1  | John |  E1   |  P1   |
| 2  | Max  |  E2   |  P2   |

我正在尝试找到索引列的最佳方法 EmailPhone考虑到查询(大多数时候)的形式为

[1] SELECT * FROM Person WHERE Email = '...' OR Phone = '...'
[2] SELECT * FROM Person WHERE Email = ...
[3] SELECT * FROM Person WHERE Phone = ...

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

CREATE NONCLUSTERED INDEX [IX_EmailPhone]
ON [dbo].[Person]([Email], [PhoneNumber]);

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

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

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

最佳答案

使用两个单独的索引,一个针对(电子邮件),另一个针对(电话、电子邮件)

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

您可以将查询编写为:

SELECT *
FROM Person 
WHERE Email = '...' 
UNION ALL
SELECT *
FROM Person 
WHERE Email <> '...' AND Phone = '...';

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

关于SQL Server 为什么索引不与 OR 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40874599/

相关文章:

android - 在第一次启动时创建 SQL 数据库并在下次启动时检索数据库数据

MySQL:强制查询在WHERE子句中使用带有局部变量的索引

MYSQL移动索引的位置

sql - 单列SUM,不是单组群函数

mysql - 列出共享完全相同的列名的所有表

sql - oracle中给定数字之前最接近的数字

SQL存储动态数据

sql - 如何从 SQL Server 中由二进制文字组成的字符串变量设置二进制值?

sql - 带左连接的输出子句,如何?

stored-procedures - 创建一个过程来检索我的表上的所有索引并重建